home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / ka9q / bpqkis01 / jkiss.s < prev    next >
Encoding:
Text File  |  1994-07-30  |  58.2 KB  |  2,272 lines

  1.  
  2. ;             KISS TNC FOR THE TNC-2 AND CLONES
  3. ;
  4. ; K3MC 30 SEP 86 - ORIGINAL VERSION
  5. ;
  6. ; 1 MAR 87.  FIXED ALL KNOWN BUGS.  RE-ARRANGE CODE TO ALLOW ROMING (THIS
  7. ; MEANS THAT DATA AREAS NEED TO BE INITIALIZED FROM THE CODE).  FIGURE OUT THE
  8. ; STACK POINTER GIVEN THE AMOUNT OF AVAILABLE RAM.  INCLUDE THE CODES 05 00
  9. ; AND 05 01 TO MEAN FULL DUPLEX OFF AND FULL DUPLEX ON, RESPECTIVELY.
  10. ; CLEAR OUT ALL AVAILABLE RAM.  DO A "DANCE" WITH LEDS WHEN INITIALLY BOOTED:
  11. ; FLASH THE LED(S) FOR ABOUT 5 SECONDS SUCH THAT CON ONLY FLASHES IF YOU HAVE
  12. ; 8K RAM, STA ONLY FLASHES IF 16K RAM, AND STA AND CON FLASH IF 32K RAM.
  13. ;
  14. ; 29 MAR 87. ADD CODE TO DISCARD BREAK CHARS, AND CHARS WITH FRAMING ERRORS.
  15. ; FIX BUG IN IB_RCA WHICH DID NOT DISCARD NULL RECEIVED FRAMES.
  16.  
  17. ;    Modified by John Wiseman, G8BPQ for use with ZILOG assembler,
  18. ;    and to reset on error conditions (underrun or buffer overload)
  19. ;
  20. ;    CWID added - june 1990
  21. ;
  22. ;    AUGUST 90 - FIX FOR 'FLAKY DCD' PROBLEM - IF DCD DROPS DURING A FRAME,
  23. ;      THEN THE FIRST PART IS JUNKED, AND THE REST TREATED AS A VALID FRAME
  24. ;
  25. ;PROM    EQU    0            ; DOWN LINE LOAD
  26. PROM    EQU    1            ; PROM VERSION
  27.  
  28.  
  29.     COND    PROM-1
  30.     ORG    8000H            ; FOR DOWN LINE LOAD
  31.     ENDC
  32.  
  33.  
  34.  
  35. FALSE    EQU    0
  36. TRUE    EQU    0FFH
  37.  
  38.  
  39. I_REGISTER    EQU    $/256
  40.  
  41. SIO    EQU    0DCH        ;ACTUALLY, ONLY A5 IS USED FOR SIO -CS
  42.  
  43. A_DAT    EQU    SIO+0        ;MODEM PORT
  44. A_CTL    EQU    SIO+1        ;MODEM PORT
  45.  
  46. B_DAT    EQU    SIO+2        ;USER SERIAL PORT
  47. B_CTL    EQU    SIO+3        ;USER SERIAL PORT
  48.  
  49. DCD    EQU    8        ;BIT IN RR0, USED IN CH A
  50.  
  51. TBE    EQU    4        ;TX BUFFER EMPTY BIT
  52. RTS    EQU    2        ;REQUEST TO SEND (PTT BIT IN WR5 OF CHAN A)
  53. FRAMING_ERROR    EQU    40H    ;BIT IN RR1 FOR ASYNC FRAMING ERROR
  54. BREAK_ABORT    EQU    80H    ;BIT IN RR0 FOR ASYNC BREAK DETECTION
  55.  
  56. FEND    EQU    300O        ;300 OCTAL
  57. FESC    EQU    333O        ;333 OCTAL
  58. TFEND    EQU    334O        ;334 OCTAL
  59. TFESC    EQU    335O        ;335 OCTAL
  60.  
  61. ALEDON    EQU    69H        ;BITS FOR WR5 TO TURN ON  STA LED
  62. ALEDOFF    EQU    0E9H        ;BITS FOR WR5 TO TURN OFF STA LED
  63.  
  64. ALED    EQU    80H        ;THE DTR BIT IN CH A WR5, WE WILL SOON REMOVE
  65.                 ;PREVIOUS 2 DEFINITIONS & USE THE MEMORY LOC.
  66.                 ;A_WR5 TO HOLD CH A WR5'S VALUE, BECAUSE WE
  67.                 ;NEED TO BE AWARE WHEN WE ARE TRANSMITTING!
  68.  
  69. BLEDON    EQU    6AH        ;BITS FOR WR5 TO TURN ON  CON LED
  70. BLEDOFF    EQU    0EAH        ;BITS FOR WR5 TO TURN OFF CON LED
  71. BLED    EQU    80H
  72.  
  73. N_EVENTS    EQU    4    ; SO FAR, ONLY 3 REAL-TIME EVENTS
  74.                 ; + CLOCK FOR CWID
  75.  
  76. START:
  77.     JP    CODE_START    ;GO AROUND THIS DATA AREA
  78. VERSION:
  79.     DEFM    'G8BPQ 16SEP90'    ;13 BYTES (EXACTLY!) HERE FOR VERSION STRING
  80.  
  81.     DEFW    IB_TBE        ;CH B TRANSMITTER BUFFER EMPTY INTERRUPT/USER
  82.     DEFW    IB_EXT        ;CH B EXT/STATUS CHANGE/USER
  83.     DEFW    IB_RCA        ;CH B RECEIVED CHAR AVAILABLE/USER
  84.     DEFW    IB_SPECIAL    ;CH B SPECIAL RECEIVE CONDITION/USER
  85.  
  86.     DEFW    IA_TBE        ;CH A TRANSMITTER BUFFER EMPTY INTERRUPT/MODEM
  87.     DEFW    IA_EXT        ;CH A EXT/STATUS CHANGE/MODEM
  88.     DEFW    IA_RCA        ;CH A RECEIVED CHAR AVAILABLE/MODEM
  89.     DEFW    IA_SPECIAL    ;CH A SPECIAL RECEIVE CONDITION/MODEM
  90.  
  91. CHANNEL    DEFB    0        ; DUMMY FOR JKISSP
  92.  
  93. CWID    DEFS    512        ; PATCH ID IN HERE - 20 BYTES PER SECOND,
  94.                 ; SO ENOUGH ROOM FOR 25 SECS OF ID!
  95.  
  96. ;
  97. A_INIT:
  98.     DEFB    18H,4,20H,1,1BH,7,7EH,5,0E9H,3,0C9H    ;FOR MODEM
  99. A_SIZE    EQU    $-A_INIT
  100.  
  101. B_INIT:
  102.     DEFB    18H,4,44H,2,10H,3,0C1H,5,0EAH,1,1FH    ;FOR TTY
  103. B_SIZE    EQU    $-B_INIT
  104.  
  105.  
  106. ;THIS IS THE DATA AREA WHICH GETS BLASTED INTO RAM UPON STARTUP:
  107. DATA_INIT:
  108.  
  109. ;NBUFFERS:
  110.         DEFB    0        ;UP TO 255 BUFFERS
  111. ;FREE:
  112.         DEFW    0        ;ADDRESS OF 1ST BUFFER ON FREE LIST
  113.  
  114. ;RX_BUF:
  115.         DEFW    0        ;ADDRESS OF CURRENT RECEIVE BUFFER
  116. ;RX_HEAD:
  117.         DEFW    0        ;ADDRESS OF 1ST RX BUFFER
  118. ;RX_ALLOCATED_BUFFER:
  119.         DEFB    0        ;SET NON-ZERO IF WE'RE IN RX STATE
  120.  
  121. ;RX_FLUSHING:
  122.         DEFB    0        ;IS NON-0 IF WE RAN OUT OF BUFFER
  123.                     ;SPACE AND ARE CURRENTLY FLUSHING THIS
  124.                     ;FRAME BEING RECEIVED.  USED BY
  125.                     ;IA_RCA AND RESET BY IA_EXT.
  126.  
  127.  
  128. ;IN_BUFFER:
  129.         DEFW    0        ;ADDR OF CURRENT INPUT BUFFER
  130. ;IN_HEAD:
  131.         DEFW    0        ;ADDR OF 1ST INPUT BUFFER
  132. ;IN_ALLOCATED_BUFFER:
  133.         DEFB    0        ;IS NOT 0 IF WE'VE ALREADY ALLOC'D BUF
  134.  
  135. ;IN_STATE:
  136.         DEFB    1        ;CONVERT BACK TO 1 IN V.32 CODE
  137.  
  138.                     ;INPUT STATE MACHINE STATE
  139.                     ;4 MAR 8: MAKE IT 0 (FROM 1) BECUZ
  140.                     ;NOISE ON LINE IS FIRST TRIGGERING THE
  141.                     ;CODE TO ASSUME THAT A FRAME IS COMING
  142.                     ;FROM THE HOST.....  COMMENT BELOW WAS
  143.                     ;APPROPRIATE BEFORE
  144.                     ;ASSUME THAT WE'VE SEEN AN FEND FROM
  145.                     ;(NON-EXISTENT) "PREVIOUS" FRAME. THIS
  146.                     ;MEANS THAT WHEN WE ARE RECEIVING DATA
  147.                     ;FROM USER, THERE NEED BE ONLY THE
  148.                     ;FEND CHAR AT THE END OF A FRAME, AND
  149.                     ;NOT AT THE BEGINNING (ALTHOUGH IF A
  150.                     ;FEND IS AT THE BEGINNING, IT IS 
  151.                     ;IGNORED.)
  152.  
  153. ;OUT_STARTED:
  154.         DEFB    0        ;OUTPUT NOT STARTED YET (LOGICAL VAR)
  155. ;OUT_HEAD_CBUF:
  156.         DEFW    OUT_TOP        ;ADDRESS OF BUFFER TO BE OUTPUT RS232
  157. ;OUT_TAIL_CBUF:
  158.         DEFW    OUT_TOP        ;POINTER TO NEXT FREE OUTPUT BUFFER
  159. ;OUT_CHAIN_HEAD:
  160.         DEFW    0        ;ADDR OF BUFFER WE ARE NOW OUTPUTTING
  161.  
  162. ;TX_STARTED:
  163.         DEFB    0        ;NON-ZERO IF WE'VE BEGUN TXING CHARS
  164. ;TX_HEAD_CBUF:
  165.         DEFW    TX_TOP        ;CURRENT ACTIVE CBUF ENTRY (IF ACTIVE)
  166. ;TX_TAIL_CBUF:
  167.         DEFW    TX_TOP        ;NEXT FREE CBUF ENTRY
  168.  
  169. ;TX_CHAIN_HEAD:
  170.         DEFW    0        ;HOLDS ADDRESS OF THE CURRENT BUFFER
  171.                     ;CHAIN HEAD THAT WE ARE TRANSMITTING
  172. ;TX_OUTSTANDING:
  173.         DEFB    0        ;NUMBER OF TX CBUFS QUEUED UP FOR TX
  174.  
  175. ;DCD_STATE:
  176.         DEFB    0        ;IS NON 0 IF DCD LED IS ON
  177.  
  178. ;THESE NEXT TWO ARE USED BY THE IB_TBE INTERRUPT ROUTINE.
  179. ;IB_ESC_MODE:
  180.         DEFB    0        ; NOT IN ESCAPED MODE 
  181. ;IB_CHAR:
  182.         DEFS    1        ; NEXT CHAR TO SEND IF ESCAPED MODE
  183. ;IN_BREAK:
  184.         DEFB    0        ; NON-ZERO IF WE ARE IN A BREAK DETECT
  185.                     ; SEQUENCE ON THE ASYNC PORT
  186. ;FULL_DUPLEX:
  187.         DEFB    0        ;NOT FULL DUPLEX TO START
  188. ;A_WR5:
  189.         DEFB    ALEDOFF        ;STATE OF STA LED & RTS (PTT) LINE,
  190.                     ;MAINLY... (FOR CH A ONLY [MODEM] )
  191. ;B_WR5:
  192.         DEFB    BLEDOFF
  193.  
  194. DATA_SIZE    EQU    $-DATA_INIT
  195.  
  196. ;***************************************************************************
  197. CODE_START:
  198.     DI                ;NO INTERRUPTS FOR THE MOMENT...
  199.  
  200. ;INIT SIO.  THIS IS REQUIRED EVEN IF WE WANNA FLASH LEDS...
  201.  
  202.     IN    A,(A_CTL)        ;ASSURE WE ARE TALKING TO CH 0
  203.     LD    C,A_CTL
  204.     LD    B,A_SIZE
  205.     LD    HL,A_INIT
  206.     OTIR                ;INIT SYNC (MODEM) PORT
  207.  
  208. ;INIT ASYNC PORT, ALSO TO ALLOW FLASHING LEDS
  209.  
  210.     IN    A,(B_CTL)        ;ASSURE WE ARE TALKING TO CH 0
  211.     LD    C,B_CTL
  212.     LD    B,B_SIZE
  213.     LD    HL,B_INIT
  214.     OTIR                ;INIT ASYNC PORT & INTERRUPT VECTOR
  215.  
  216. ;
  217. ; FIGURE OUT WHERE TOP OF STACK IS, SET STACK POINTER.
  218. ; SILLY TNC-2 DOES NOT DO COMPLETE ADDRESS DECODING FOR THE RAMS IF YOU ARE
  219. ; USING ONLY THE TWO 8K X 8 CHIPS.  HACK TO FIGURE OUT TOP OF MEMORY SO WE CAN
  220. ; SET STACK POINTER. NEWER HACK TO SEE IF WE'VE ONLY GOT 8K RAM.
  221.  
  222.     LD    A,(9FFFH)    ;TOP OF RAM IF ONLY 8K
  223.     CPL
  224.     LD    B,A
  225.     LD    (9FFFH),A    ;WRITE ONE'S COMPLEMENT INTO MEM
  226.  
  227.     LD    A,(9FFFH)    
  228.     CP    B        ;SEE IF IT "TOOK"
  229.     JP    Z,OK_8        ;YES, WE HAVE AT LEAST 8K OF RAM
  230.  
  231.  
  232.     HALT            ;ELSE THERE IS NO RAM, SO STOP
  233.  
  234. OK_8:
  235.     LD    A,(0BFFFH)    ;TOP OF RAM IF 16K
  236.     CPL
  237.     LD    B,A
  238.     LD    (0BFFFH),A    ;SAME ONE'S COMPLEMENT HACK
  239.  
  240.     LD    A,(0BFFFH)
  241.     CP    B
  242.     JP    Z,OK_16        ;WE HAVE AT LEAST 16K OF RAM
  243.  
  244.     LD    SP,0A000H
  245.     LD    D,0FFH        ;BLINK CON LED
  246.     LD    E,0        ;BUT NOT STA LED  (I.E., WE HAVE 8K)
  247.     JP    STACK_LOADED    ;ELSE WE ONLY HAVE 8K OF RAM
  248.                 ;BECAUSE PREVIOUS COMPARE FAILED
  249.  
  250. ;HERE IF WE'VE GOT AT LEAST 16K RAM
  251. OK_16:
  252.     LD    A,55H        ;ONE VALUE
  253.     LD    (0BFFFH),A
  254.     LD    A,0AAH
  255.     LD    (0FFFFH),A    ;OTHER VALUE
  256.  
  257.     LD    A,(0BFFFH)    ;GET WHAT SHOULD BE 55H IF 32K
  258.  
  259.     CP    55H        
  260.     LD    SP,0
  261.     LD    DE,0FFFFH    ;BLINK BOTH CON AND STA LEDS (IF 32K)
  262.     JR    Z,STACK_LOADED    ;IF IS 55H, THEN WE'VE GOT 32 K, ELSE 16 K
  263.  
  264.     LD    SP,0C000H    ;FORCE STACK VALUE.
  265.     LD    D,0        ;DO NOT BLINK CON LED IF 16K RAM
  266.  
  267. STACK_LOADED:
  268.     PUSH    DE        ;DE HAS LOGICAL VALUES WHICH TELL US WHICH
  269.                 ;LEDS TO FLASH (WHICH WE DO LATER...)
  270.     EXX
  271.     POP    HL        ;TEMP. STORE THIS INFO IN OTHER REG SET
  272.     EXX
  273.  
  274.  
  275. ;CLEAR OUT RAM.
  276.  
  277.     LD    HL,0
  278.     ADD    HL,SP        ;NOW HL HAS VALUE OF SP (THAT IS, TOP OF
  279.                 ;MEMORY + 1)
  280.     DEC    HL        ;NOW HL HAS TOP OF MEMORY ADDRESS
  281.     LD    DE,FREE_RAM    ;GET START OF AVAILABLE FREE RAM
  282.     XOR    A        ;CLEAR CARRY AND SET A TO 0
  283.     LD    (DE),A        ;FIRST FREE RAM LOCATION IS ZEROED....
  284.     SBC    HL,DE        ;GET INTO HL # OF BYTES OF FREE RAM.  IF WE 
  285.                 ;ARE IN ROM, THEN ALL RAM IS FREE, ELSE IF WE
  286.                 ;ARE RUNNING FROM RAM, THE CODE PART IS NOT
  287.                 ;FREE, AND THIS COMPENSATES FOR THIS.
  288.  
  289.     DEC    HL        ;ONE FEWER BYTES FOR NUMBER TO MOVE...
  290.     LD    B,H
  291.     LD    C,L        ;GET BYTE COUNT INTO BC
  292.  
  293.     LD    H,D
  294.     LD    L,E        ;GET "SOURCE" ADDRESS = FREE_RAM
  295.  
  296.     INC    DE        ;SET "DESTINATION" ADDRESS = FREE_RAM + 1
  297.  
  298.     LDIR            ;ZERO MEMORY.
  299.  
  300. ;THIS SEQUENCE LOADS UP OUR DATA AREA IN RAM:
  301.  
  302.     LD    HL,DATA_INIT
  303.     LD    DE,NBUFFERS
  304.     LD    BC,DATA_SIZE
  305.     LDIR
  306.  
  307.  
  308. ; SET STACK SIZE AND INIT FREE BUFFER LIST.
  309.  
  310.     LD    HL,0
  311.     ADD    HL,SP            ;GET VALUE OF SP, HIGH MEMORY
  312.     LD    DE,100            ;50 WORDS FOR STACK
  313.     OR    A            ;CLEAR CARRY
  314.     SBC    HL,DE            ;NOW HL HAS "PSEUDO TOP OF MEMORY"
  315.     LD    DE,BOTTOM        ;"PSEUDO BOTTOM OF MEMORY"
  316.     OR    A
  317.     SBC    HL,DE            ;HL NOW HAS SIZE OF AVAILABLE MEMORY
  318.     RL    L            ;PUT MSB INTO CARRY
  319.     RL    H            ;PUT CARRY INTO LSB
  320.                     ;NOW H HAS NUMBER OF BUFFERS AVAILABLE
  321.     LD    A,H
  322.     LD    (NBUFFERS),A        ;SAVE THIS NUMBER IN MEMORY
  323.  
  324.     LD    HL,BOTTOM        ;BEGINNING OF BUFFER SPACE
  325.     LD    (FREE),HL        ;NOW IT'S ALSO TOP OF FREE LIST
  326. ; INIT BUFFER FREE LIST
  327.     LD    B,A            ;GET NBUFFERS (SEE ABOVE)
  328.     DEC    B            ;BECAUSE LAST ONE HAS 0 AS "NEXT"
  329. IBLOOP:
  330.     PUSH    HL
  331.     LD    DE,128
  332.     ADD    HL,DE            ;HL HAS "NEXT" POINTER
  333.     EX    DE,HL            ;DE HAS "NEXT" POINTER
  334.     POP    HL            ;HL NOW HAS POINTER TO CURRENT BUFFER
  335.  
  336.     LD    (HL),E            ;LOW BYTE OF "NEXT" POINTER FIRST
  337.     INC    HL
  338.     LD    (HL),D            ;NOW HI BYTE
  339.     INC    HL
  340.     XOR    A
  341.     LD    (HL),A            ;ZERO OUT COUNT FIELD
  342.     INC    HL
  343.     LD    (HL),A            ;ZERO OUT # OF BYTES READ FIELD
  344.  
  345.     EX    DE,HL            ;HL IS NOW POINTER TO NEXT BUFFER
  346.     DJNZ    IBLOOP            ;AND INIT ALL THE AVAILABLE BUFFERS
  347.  
  348.     XOR    A
  349.     LD    (HL),A            ;LAST "NEXT" ADDRESS IS 0
  350.     INC    HL
  351.     LD    (HL),A            ;DITTO
  352.  
  353.     INC    HL
  354.     LD    (HL),A            ;ZERO OUT COUNT FIELD
  355.     INC    HL
  356.     LD    (HL),A            ;ZERO OUT # OF BYTES READ FIELD
  357.  
  358. ;INIT REGS FOR IB_EXT INTERRUPT
  359.     EXX
  360.     LD    BC,0            ;SET PREV STATE OF SYNC PIN,FOR 1200HZ
  361.     LD    DE,0            ;COUNT OF # OF INTERRUPTS INIT
  362.     EXX
  363.  
  364.     XOR    A
  365.     LD    (RX_ALLOCATED_BUFFER),A        ;NOT RECEIVING AT THIS TIME
  366.  
  367.     LD    HL,TXQ_ENABLES
  368.     LD    B,N_EVENTS
  369. E_CLEAR:
  370.     LD    (HL),A            ; TURN OFF ALL THE ENABLES OF ALL ...
  371.     INC    HL            ; ... POSSIBLE EVENTS.
  372.     DJNZ    E_CLEAR
  373.  
  374. ;INIT THE ROUTINE ADDRESSES IN OUR EVENT TABLE
  375.  
  376.     LD    HL,R_DELAY
  377.     LD    (TXQ_ADDRESSES),HL
  378.     LD    HL,R_SLOTTIME
  379.     LD    (TXQ_ADDRESSES+2),HL
  380.     LD    HL,R_TAIL
  381.     LD    (TXQ_ADDRESSES+4),HL
  382.  
  383.     LD    A,(CWID)
  384.     CP    0FFH
  385.     JR    Z,SKIPID        ; NO CWID DEFINED
  386.  
  387.     LD    HL,RTCLOCK
  388.     LD    (TXQ_ADDRESSES+6),HL    ; REAL TIME CLOCK FOR CWID
  389. ;
  390. ;    ENABLE RTC FOR CWID
  391. ;
  392.     LD    HL,6000            ; MINUTE IN 1/100THS OF SEC
  393.     LD    (TXQT_CWID),HL        ; GET TIMER VALUE INTO TIMER SLOT
  394.     LD    A,1
  395.     LD    (TXQE_CWID),A        ; ENABLE THIS EVENT
  396.     LD    (MINUTES),A        ; SEND FIRST AFTER 1 MINUTE
  397.  
  398. SKIPID:
  399.  
  400.     LD    A,50
  401.     LD    (TXDELAY),A        ; TX DELAY DEFAULT IS 500 MS
  402.      LD    A,64
  403.     LD    (PERSISTENCE),A        ; SET DEFAULT VALUE FOR PERSISTENCE
  404.     LD    A,10
  405.     LD    (SLOTTIME),A        ; AND SLOT TIME DEFAULTS TO 100 MS
  406.     LD    A,3
  407.     LD    (TAILTIME),A        ;TAIL TIMER DEFAULT
  408.  
  409.  
  410. ; NOW HAVE THE CON AND STA LEDS DO A "DANCE".
  411.  
  412.     EXX
  413.     PUSH    HL
  414.     EXX
  415.     POP    DE        ;WE SAVED THE LOGICALS TELLING US WHICH LEDS
  416.                 ;TO FLASH WHEN WE FIGURED OUT THE STACKSIZE.
  417.                 ;THIS IS HOW WE KNOW WHICH LEDS TO BLINK.
  418.  
  419.     LD    B,6        ;DO IT 6 TIMES (ARBITRARY AS HELL, BUT SHOULD
  420.                 ;BE AN EVEN NUMBER SO THAT THE LEDS ARE OFF AT
  421.                 ;THE END OF THIS MESS...)
  422.     LD    HL,0        ;USE HL AS DOWNCOUNTER
  423. DANCE0:
  424.     LD    A,D
  425.     OR    A
  426.     CALL    NZ,CON_FLIP
  427.     LD    A,E
  428.     OR    A
  429.     CALL    NZ,STA_FLIP
  430. DANCE1:
  431.     DEC    HL
  432.     LD    A,H
  433.     OR    L
  434.     JP    NZ,DANCE1
  435.  
  436.     DJNZ    DANCE0        ;DO THIS 6 TIMES  (3 "CYCLES")
  437.  
  438. ;PREVIOUS STUFF SHOWED THAT THE DOWNLOAD OR BOOT WORKED PROPERLY...
  439.  
  440.  
  441.  
  442. ;WE RE-INITIALIZE THE SIO PORTS SO THAT WE FLUSH GARBAGE CHARS THAT MAY HAVE
  443. ;COME IN WHILE WE WERE DIDDLING THE LEDS.  THIS IS NECESSARY BECAUSE UNLESS WE
  444. ;DO THIS, THEN THE A CHANNEL (MODEM) GET RX OVERRUN (ESP IF TNC WAS LISTENING
  445. ;TO NOISE) AND RX OVERRUN IS VERY BAD - SO BAD, IN FACT, THAT I TURN ON BOTH
  446. ;CON AND STA AND HALT, BECAUSE THIS SITUATION SHOULD NEVER HAPPEN IN NORMAL
  447. ;USE.  I FLUSH THE B (TTY) CHANNEL IN CASE ANYTHING WAS SENT TO IT IN MID-
  448. ;STREAM.
  449.  
  450.  
  451. ;RE-INIT SIO.
  452.  
  453.     IN    A,(A_CTL)        ;ASSURE WE ARE TALKING TO CH 0
  454.     LD    C,A_CTL
  455.     LD    B,A_SIZE
  456.     LD    HL,A_INIT
  457.     OTIR                ;INIT SYNC (MODEM) PORT
  458.  
  459. ;RE-INIT ASYNC PORT.
  460.  
  461.     IN    A,(B_CTL)        ;ASSURE WE ARE TALKING TO CH 0
  462.     LD    C,B_CTL
  463.     LD    B,B_SIZE
  464.     LD    HL,B_INIT
  465.     OTIR                ;INIT ASYNC PORT & INTERRUPT VECTOR
  466.  
  467.  
  468. ; PREPARE TO LOAD HI BITS OF INTERRUPT VECTOR
  469.  
  470.     LD    A,I_REGISTER
  471.     LD    I,A            ;SET INTERRUPT PAGE FOR MODE 2 INTS
  472.     IM    2
  473.     EI                ;LET 'EM RIP!
  474.  
  475. ;-----------------------------------------------------------------------------
  476. ; THIS IS THE BACKGROUND PROGRAM.
  477. ; NOTE THAT SINCE EVERYTHING ELSE IS INTERRUPT DRIVEN, AND SAVES REGISTERS,
  478. ; THIS PART OF THE CODE CAN USE REGISTERS & EXPECT VALUES TO STAY.
  479.  
  480. COMMUTATOR_LOOP:
  481. ;
  482. ;    SEE IF ID NEEDED
  483. ;
  484.     LD    A,(CWIDFLAG)
  485.     OR    A
  486.     JR    NZ,TRY_ID
  487.  
  488.     LD    A,(TX_OUTSTANDING)    ;IF THERE ARE NO OUTSTANDING TX...
  489.     OR    A            ;...FRAMES, THEN WE DON'T HAVE TO...
  490.     JP    Z,SCAN_CHECK        ;...WORRY ABOUT TRANSMITTER
  491.  
  492. TRY_ID:
  493. ;
  494. ; IF THERE ARE FRAMES TO TRANSMIT, WE MAY HAVE TURNED ON TXDELAY, OR WE MAY BE
  495. ; TRANSMITTING A FRAME SO CHECK FIRST.
  496. ; (THIS BUG FOUND LATE ON 30 SEP 86)  THE CLEANEST WAY TO DO 
  497. ; THIS IS TO CHECK IF WE ARE KEYED UP.  IF SO, NOTHING ELSE TO DO FOR NOW
  498. ; HERE.  THIS IS THE "LAST BUG!"  FOUND AT 11:59PM EDT ON 30 SEP.
  499.  
  500.     LD    A,(A_WR5)
  501.     AND    RTS
  502.     JP    NZ,SCAN_CHECK        ;IF TX KEYED UP, NOTHING FOR US TO
  503.                     ;DO HERE!
  504. ;
  505. ;    ELSE WE'VE NOTICED THAT WE'VE GOT SOME FRAME(S) TO SEND.
  506. ;      TRY TO KEYUP TX
  507.  
  508.     LD    A,(FULL_DUPLEX)
  509.     OR    A
  510.     JP    NZ,KEY_UP        ;IF FULL DUPLEX, THEN THERE IS NO
  511.                     ;NEED TO WORRY ABOUT ALL THIS SILLY
  512.                     ;SLOT TIME AND PERSISTENCE STUFF!
  513.  
  514.     LD    A,(TXQE_SLOTTIME)    ;GET SLOTTIME TIMER ENABLE
  515.     OR    A
  516.     JP    NZ,SCAN_CHECK        ;IF WE'RE WAITING, KEEP WAITING!
  517.  
  518. ;CHECK IF CARRIER DETECT IS ACTIVE
  519.  
  520.     LD    A,(DCD_STATE)        ;DCD_STATE IS SET IN INTERRUPT ROUTINE
  521.     OR    A
  522.     JP    NZ,SCAN_CHECK        ;IF CARRIER ACTIVE, WAIT IT OUT
  523.  
  524. ;SO, DCD IS INACTIVE; DO PERSISTENCE ALGORITHM
  525.  
  526.     LD    A,R            ;GRAB THE Z-80 REFRESH REGISTER
  527.     ADD    A,A            ;DOUBLE;NOW 0 <= A REG <= 254
  528.     LD    B,A            ;B HOLDS OUR "RANDOM" NUMBER
  529.     LD    A,(PERSISTENCE)
  530.     SUB    B            ;A REG = PERSISTENCE - RANDOM #
  531.     JP    C,NO_PTT        ;IF (P-R) < 0 THEN NO PTT NOW
  532.                     ; NOTE THAT P=255 MEANS ALWAYS KEY UP
  533.  
  534. ;OK, SO WE'VE WON WITH THE RANDOM NUMBER GENERATOR.  KEYUP TX AND START THE
  535. ;TXDELAY TIMER
  536.  
  537. KEY_UP:
  538. ;
  539. ;    SEE IF ID NEEDED
  540. ;
  541.     LD    A,(CWIDFLAG)
  542.     OR    A
  543.     JP    Z,NO_ID
  544.  
  545.     CALL    STARTID
  546.  
  547.     JP    SCAN_CHECK
  548.  
  549. NO_ID:
  550.  
  551.     LD    A,(TXDELAY)
  552.     LD    H,0
  553.     LD    L,A            ;HL IS 16-BIT VALUE OF TXDELAY
  554.     LD    (TXQT_DELAY),HL        ;GET TIMER VALUE INTO TIMER SLOT
  555.     LD    A,1
  556.     LD    (TXQE_DELAY),A        ;ENABLE THIS EVENT
  557.  
  558.     LD    A,5
  559.     DI                ;WE NEED QUITE TIME HERE.
  560.     OUT    (A_CTL),A        ;;;READY TO WRITE INTO WR5 OF CH A
  561.     LD    A,(A_WR5)
  562.     OR    RTS            ;;;TURN ON THE PTT BIT...
  563.     LD    (A_WR5),A        ;;;...IN THE MEMORY COPY OF WR5
  564.     OUT    (A_CTL),A        ;;; KEYUP TRANSMITTER
  565.     EI
  566.     JP    SCAN_CHECK        ;THAT'S ALL WE DO FOR NOW, WE AWAIT
  567.                     ;TXDELAY EVENT
  568.  
  569. NO_PTT:
  570. ;
  571. ;    SINCE WE LOST ON RANDOM #, WAIT SLOTTIME BEFORE TRYING AGAIN
  572. ;
  573.     LD    A,(SLOTTIME)
  574.     LD    H,0
  575.     LD    L,A            ;HL HAS 16-BIT VERSION OF SLOTTIME
  576.     LD    (TXQT_SLOTTIME),HL    ;SET UP THE TIMER VALUE OF THIS EVENT
  577.     LD    A,1
  578.     LD    (TXQE_SLOTTIME),A    ;AND ENABLE THIS EVENT
  579.  
  580. ; NOTE THAT THIS CODE DOES NOT HAVE TO BE INTERRUPT PROTECTED BECAUSE WE
  581. ; REALLY DON'T CARE IF THE SLOT TIMER IS DECREMENTED BETWEEN BEING LOADED
  582. ; AND BEING ENABLED.
  583.  
  584. SCAN_CHECK:
  585.  
  586.     LD    HL,TXQ_ENABLES        ; GEAR UP TO CHECK TIMER ROUTINES
  587.     LD    IX,TXQ_TIMERS
  588.     LD    IY,TXQ_ADDRESSES
  589.     LD    DE,2            ;BUMP IX & IY BY TWOS
  590.     LD    B,N_EVENTS        ;NUMBER OF POSSIBLE EVENTS
  591. SCAN_TOP:
  592.     LD    A,(HL)
  593.     OR    A
  594.     JP    Z,SCAN_BOTTOM        ;IF NOT ENABLED, CHECK NEXT ONE
  595.  
  596. ;ELSE IS ENABLED.  TIMER EXPIRED?
  597.  
  598.     LD    A,(IX+1)
  599.     LD    C,A            ;SAVE MS BYTE FOR POSSIBLE USE LATER
  600.     OR    (IX)
  601.     JR    Z,SCAN_FIRE        ;FIRE THIS IF WE ARE AT 0 COUNT
  602.  
  603.     LD    A,C
  604.     OR    A            ; SAVES US SOME TIME DOING IT THIS WAY
  605.     JP    P,SCAN_BOTTOM        ; OR FIRE IF WE ARE NEGATIVE
  606.  
  607. SCAN_FIRE:
  608.     XOR    A
  609.     LD    (HL),A            ;DISABLE THIS EVENT AS IT FIRES
  610.     PUSH    HL
  611.     LD    HL,SCAN_RETURN        ;LOAD UP ROUTINE RETURN ADDRESS
  612.     PUSH    HL            ;SAVE AS RETURN ADDRESS ON STACK
  613.     LD    H,(IY+1)
  614.     LD    L,(IY)            ;GET ADDRESS OF ROUTINE TO "CALL"
  615.     JP    (HL)            ;"CALL" THIS ROUTINE
  616.  
  617. SCAN_RETURN:                ;WHERE ALL ROUTINES RETURN
  618.  
  619.     POP    HL            ;GET ORIGINAL HL BACK
  620.  
  621. SCAN_BOTTOM:
  622.     INC    HL            ;INCREMENT ENABLE TABLE POINTER
  623.     ADD    IX,DE            ;KEEP TIMER TABLE POINTER IN STEP
  624.     ADD    IY,DE            ;KEEP ROUTINE TABLE POINTER IN STEP
  625.     DJNZ    SCAN_TOP        ;LOOK AT ALL ENTRIES IN TABLES
  626.  
  627.  
  628. ;NOW SEE IF WE NEED TO START AN OUTPUT TO RS-232 (HOST) PORT
  629.     LD    A,(OUT_STARTED)
  630.     OR    A            ;ALSO CLEARS CARRY (SEE BELOW) 
  631.     JP    NZ,COMMUTATOR_LOOP    ;IF OUTPUT STARTED, NOTHING TO DO
  632.  
  633. ; ELSE WE SHOULD CHECK TO SEE IF WE NEED TO START AN OUTPUT
  634.     DI
  635.     CALL    CON_OFF            ;;;
  636.     LD    HL,(OUT_HEAD_CBUF)    ;;;GRAB CURRENT TOP OF CIRC BUF PTR
  637.     LD    DE,(OUT_TAIL_CBUF)    ;;;AND WHERE THE NEXT FREE BUF PTR IS
  638.     EI
  639.                     ;INTERRUPT PROTECT THE PICKUP OF THE
  640.                     ;TWO POINTERS 3 FEB 87
  641.     OR    A
  642.     SBC    HL,DE
  643.     JP    Z,COMMUTATOR_LOOP    ;IF THE SAME, NOTHING TO DO
  644.  
  645. ;ELSE WE NEED TO START AN OUTPUT
  646.     DI                ;INTERRUPT PROTECT THIS SECTION,
  647.                     ;ALTHOUGH I'M NOT SURE IT NEEDS IT...
  648.                     ;3 FEB 87
  649.                     ;NOTE: IT SHOULD ALREADY BE DONE!
  650.     LD    HL,(OUT_HEAD_CBUF)    ;;;GET POINTER TO NEXT CBUF TO OUTPUT
  651.     LD    E,(HL)
  652.     INC    HL
  653.     LD    D,(HL)            ;;;DE HAS POINTER TO BUFFER CHAIN
  654.     LD    (OUT_CHAIN_HEAD),DE    ;;;SET IN INTERRUPT ROUTINE'S PLACE
  655.     LD    A,1
  656.     LD    (OUT_STARTED),A        ;;;YES, OUTPUT STARTED
  657.  
  658.     CALL    CON_ON    
  659. CL_0:
  660.     IN    A,(B_CTL)        ;;;LOOK AT RR0
  661.     AND    TBE            ;;;ISOLATE THE TBE BIT
  662.     JR    Z,CL_0            ;;;WAIT FOR TRANSMITTER TO GET DONE
  663.  
  664.     LD    A,FEND
  665.     OUT    (B_DAT),A        ;;;SEND FEND CHARACTER (START TXING)
  666.     EI
  667.  
  668.     JP    COMMUTATOR_LOOP        ;KEEP LOOKING FOR NEW OPPORTUNITY
  669.  
  670. RTCLOCK:
  671. ;
  672. ;    COUNT DOWN MINUTES TO KICK OFF CWID
  673. ;
  674.     LD    HL,6000            ; MINUTE IN 1/100THS OF SEC
  675.     LD    (TXQT_CWID),HL        ; GET TIMER VALUE INTO TIMER SLOT
  676.     LD    A,1
  677.     LD    (TXQE_CWID),A        ; ENABLE THIS EVENT
  678.  
  679.     LD    A,(MINUTES)
  680.     DEC    A
  681.     LD    (MINUTES),A
  682.     RET    NZ
  683. ;
  684.     INC    A
  685.     LD    (CWIDFLAG),A        ; SHOW WE NEED AN ID
  686.  
  687.     RET
  688. ;    
  689. STARTID:
  690. ;
  691. ;    SET TIMER TO GO TO NEXT CWID STATE
  692. ;
  693.     LD    HL,IDEVENT
  694.     LD    (TXQ_ADDRESSES+6),HL    ; REAL TIME EVENT FOR CWID
  695. ;
  696.     LD    HL,6            ; 20HZ BAUD RATE FOR CWID
  697.     LD    (TXQT_CWID),HL        ; GET TIMER VALUE INTO TIMER SLOT
  698.     LD    A,1
  699.     LD    (TXQE_CWID),A        ; ENABLE THIS EVENT
  700. ;
  701. ;    RAISE RTS - NEXT TIMER EVENT WILL SEND FIRST BIT
  702. ;
  703.     LD    HL,CWID
  704.     LD    (CWIDPTR),HL
  705.  
  706.     XOR    A
  707.     LD    (CWIDFLAG),A
  708.     LD    (LASTBIT),A
  709. ;
  710. ;    ENTER SYNC MODE SO WE CAN CONTROL TONES
  711. ;
  712.     DI
  713.     LD    A,1
  714.     OUT    (A_CTL),A
  715.  
  716.     XOR    A
  717.     OUT    (A_CTL),A        ; INTERRUPTS OFF
  718.  
  719.     LD    A,4
  720.     OUT    (A_CTL),A
  721.  
  722.     LD    A,00010000B        ; SYNC
  723.     OUT    (A_CTL),A
  724.  
  725.     LD    A,6
  726.     OUT    (A_CTL),A
  727.  
  728.     LD    A,0FFH
  729.     OUT    (A_CTL),A        ; SYNC CHARS
  730.  
  731.     LD    A,7
  732.     OUT    (A_CTL),A
  733.  
  734.     LD    A,0FFH
  735.     OUT    (A_CTL),A        ; SYNC CHARS
  736.  
  737.     LD    A,5
  738.     OUT    (A_CTL),A
  739.  
  740.     LD    A,11101011B        ; RAISE RTS + TXENABLE
  741.     LD    (A_WR5),A
  742.     OUT    (A_CTL),A
  743. ;
  744.     EI
  745.     RET
  746.  
  747.  
  748.  
  749. IDEVENT:
  750. ;
  751. ;    60 MS HAS PASSED - GO TO NEXT STATE
  752. ;
  753.  
  754.     LD    HL,6            ; 20HZ BAUD RATE FOR CWID
  755.     LD    (TXQT_CWID),HL        ; GET TIMER VALUE INTO TIMER SLOT
  756.     LD    A,1
  757.     LD    (TXQE_CWID),A        ; ENABLE THIS EVENT
  758. ;
  759.     LD    HL,(CWIDPTR)
  760.     LD    A,(HL)
  761.     INC    HL
  762.     LD    (CWIDPTR),HL
  763.  
  764.     CP    0FFH
  765.     JP    Z,ENDID
  766.  
  767.     LD    HL,LASTBIT
  768.     CP    (HL)
  769.     RET    Z            ; NO CHANGE
  770.  
  771.     LD    (HL),A            ; SAVE NEW STATE
  772.  
  773.     LD    A,7FH
  774.     OUT    (A_DAT),A        ; TOGGLE TONE
  775.  
  776.     RET
  777. ;
  778.  
  779. ENDID:
  780. ;
  781. ;    RESET REAL TIME EVENT TO COUNT DOWN FOR NEXT ID (29 MINS)
  782. ;
  783.     PUSH    BC
  784.  
  785.     DI
  786.  
  787.     IN    A,(A_CTL)        ;ASSURE WE ARE TALKING TO CH 0
  788.     LD    C,A_CTL
  789.     LD    B,A_SIZE
  790.     LD    HL,A_INIT
  791.     OTIR                ;INIT SYNC (MODEM) PORT
  792.  
  793.     LD    A,0E9H
  794.     LD    (A_WR5),A
  795.  
  796.     EI
  797.  
  798.     POP    BC
  799.  
  800.     LD    HL,RTCLOCK
  801.     LD    (TXQ_ADDRESSES+6),HL    ; REAL TIME CLOCK FOR CWID
  802. ;
  803.     LD    HL,6000            ; MINUTE IN 1/100THS OF SEC
  804.     LD    (TXQT_CWID),HL        ; GET TIMER VALUE INTO TIMER SLOT
  805.     LD    A,1
  806.     LD    (TXQE_CWID),A        ; ENABLE THIS EVENT
  807.  
  808.     LD    A,29
  809.     LD    (MINUTES),A
  810.  
  811.     RET
  812.  
  813. ;*****************************************************************************
  814. ; TIMER-DRIVEN EVENTS
  815. ;*****************************************************************************
  816.  
  817. ;-----------------------------------------------------------------------------
  818. R_DELAY:    ; THIS ROUTINE EXECUTES WHEN THE TX DELAY TIMER EXPIRES.
  819.     PUSH    AF
  820.     PUSH    BC
  821.     PUSH    DE
  822.     PUSH    HL
  823.     DI
  824.     CALL    TXNEXT_CBUF        ;GETS HL TO POINT TO BUFFER CHAIN, AND
  825.                     ;SETS TX_CHAIN_HEAD FOR THE INTERRUPT
  826.                     ;ROUTINE
  827.     LD    A,80H
  828.     OUT    (A_CTL),A        ;;; RESET TX CRC
  829.     CALL    GETCHAR            ;;; GETCHAR NEEDS INT. PROTECTION
  830.     OUT    (A_DAT),A        ;;; SHIP THIS CHAR TO TX MODEM
  831.     LD    A,1
  832.     LD    (TX_STARTED),A        ;;; AND, YES VIRGINA, WE'VE STARTED TX
  833.     LD    A,0C0H
  834.     OUT    (A_CTL),A        ;;; RESET TX UNDERRUN/EOM LATCH
  835.     POP    HL
  836.     POP    DE
  837.     POP    BC
  838.     POP    AF
  839.     EI
  840.     RET
  841.  
  842. ;-----------------------------------------------------------------------------
  843.  
  844. R_SLOTTIME:    ;WHEN SLOTTIME EVENT TIMER EXPIRES, COME HERE.
  845.     RET                ; WE WERE JUST WAITING, SO NOTHING
  846.                     ; ELSE TO DO HERE (!)
  847.  
  848. ;-----------------------------------------------------------------------------
  849.  
  850. R_TAIL:        ;WHEN TAIL TIMER TIMES OUT, TURN OFF THE TX
  851.  
  852.     PUSH    AF
  853.     LD    A,5            ;READY TO WRITE TO WR5 OF CH A
  854.     DI                ;;;MUST HAVE ATOMIC USE OF A_WR5 & SIO
  855.     OUT    (A_CTL),A        ;;;NEXT CHAR TO A_CTL GOES TO WR5
  856.     LD    A,(A_WR5)            ;;;GRAB A_WR5
  857.     AND    0FFH-RTS            ;;;TURN OFF RTS BIT THERE
  858.     LD    (A_WR5),A            ;;;KEEP MEMORY COPY UPDATED
  859.     OUT    (A_CTL),A        ;;;AND TURN OFF TX NOW
  860.     EI
  861.     POP    AF
  862.     RET
  863.  
  864. ;    INCLUDE    IA.MAC            ;MODEM INTERRUPT CATCHERS
  865. ;;;---------------------------------------------------------------------------
  866. IA_TBE:
  867.     PUSH    AF
  868.     PUSH    HL
  869.     LD    A,(TX_STARTED)
  870.     OR    A
  871.     JP    Z,IA_T2        ;;; PREVIOUS FRAME FINISHED
  872.  
  873.     LD    HL,(TX_CHAIN_HEAD)
  874.     CALL    GETCHAR
  875.     LD    (TX_CHAIN_HEAD),HL    ;;; MUST KEEP THIS POINTER UPDATED
  876.     JR    Z,IA_T1        ;;; NO MORE TO SEND
  877.  
  878.     OUT    (A_DAT),A    ;;; ELSE SHIP THIS CHAR OUT
  879. IA_T9:
  880.     POP    HL
  881.     POP    AF
  882.     EI
  883.     RETI            ;;; JUST RETURN FROM THESE INTERRUPTS
  884.  
  885. IA_T1:
  886. ;    HALT            ;;;IF IT GETS HERE, HALT
  887.     XOR    A
  888.     LD    (TX_STARTED),A        ;;; TX IS NOT STARTED
  889.     LD    HL,TX_OUTSTANDING    ;;; MAKE IS SO THAT ONE FEWER FRAMES
  890.                     ;;; NOT "(TX_OUTSTANDING)" (!) 29 SEP
  891.     DEC    (HL)            ;;; ARE OUTSTANDING
  892.     LD    A,28H
  893.     OUT    (A_CTL),A        ;;; RESET TX INTERRUPT PENDING
  894.     JP    IA_T9
  895.  
  896. ;;;PREVIOUS FRAME IS DONE, SIO NOW SENDING A FLAG.  MORE?
  897. IA_T2:
  898.     LD    A,(TX_OUTSTANDING)
  899.     OR    A
  900.     JP    NZ,IA_T21        ;;;IF MORE TO SEND, GO THERE
  901.  
  902. ;;; ELSE WE'RE DONE HERE, CLEAN UP.
  903.     LD    A,28H
  904.     OUT    (A_CTL),A        ;;; RESET TX INTERRUPT PENDING
  905.  
  906. ;START TAIL TIMER EVENT
  907.     LD    A,(TAILTIME)        ;;; { BUG FOUND 30 SEP.  IT WAS:
  908.     LD    H,0            ;;; "LD HL,(TAILTIME)"
  909.     LD    L,A            ;;; [OUCH!] }
  910.     LD    (TXQT_TAIL),HL        ;;; WAIT FOR CRC TO CLEAR TX
  911.     LD    A,1            ;;; 8.33 MS/CHAR AT 1200 BPS
  912.     LD    (TXQE_TAIL),A        ;;; TAILTIME VALUE SHOULD BE >=2.
  913.     JP    IA_T9
  914.  
  915. IA_T21:            ;START UP NEXT FRAME
  916.     CALL    TXNEXT_CBUF        ;;; GET THE NEXT BUFFER CHAIN POINTER
  917.                     ;;; SETUP HL AND TX_CHAIN_HEAD
  918.     LD    A,80H
  919.     OUT    (A_CTL),A        ;;; RESET TX CRC GENERATOR
  920.     CALL    GETCHAR
  921.     OUT    (A_DAT),A        ;;;GET 1ST CHAR OF NEXT FRAME
  922.     LD    A,1
  923.     LD    (TX_STARTED),A        ;;; TX STARTED AGAIN
  924.     LD    A,0C0H
  925.     OUT    (A_CTL),A        ;;; RESET TX UNDERRUN/EOM LATCH
  926.     JP    IA_T9
  927.  
  928. ;;;---------------------------------------------------------------------------
  929. ;;; GOT A CHARACTER FROM THE SIO RX INTERRUPT, DEAL WITH IT
  930. ;;; EXTENSIVE MODS 3 FEB 87 TO BE IN LINE WITH WHAT I NOW KNOW ABOUT SIO...
  931.  
  932. IA_RCA:
  933.     PUSH    AF
  934.     PUSH    HL
  935.  
  936.     LD    A,(RX_ALLOCATED_BUFFER)
  937.     OR    A
  938.     JP    NZ,IA_RC7    ;;; GO THERE IF WE ARE IN "RECEIVING" STATE
  939.  
  940. ;ELSE WE ARE NOT YET RECEIVING, SO ALLOCATE BUFFER & MAKE US "RECEIVING"
  941.  
  942.     CALL    ALLOCATE_BUFFER    ;;; GET A NEW BUFFER
  943.     JP    Z,RESTART        ; BPQ  IA_RC5    ;;; NO ROOM, FLUSH THIS FRAME
  944.  
  945. ;;; IF GOT A BUFFER, INSERT THIS CHARACTER.
  946. ;;; AFTER DOING INITIAL BUFFER SETUP.
  947.  
  948. IA_RC6:
  949.     LD    (RX_HEAD),HL    ;;; SAVE CHAIN HEAD ADDRESS (1ST BUFFER)
  950.     LD    (RX_BUF),HL    ;;; TUCK AWAY ADDR OF OUR CURRENT BUFFER
  951.     LD    A,TRUE
  952.     LD    (RX_ALLOCATED_BUFFER),A    ;;; AND MARK THAT WE ARE RECEIVING
  953.  
  954.     XOR    A
  955.     CALL    PUTCHAR        ;;; SLIP' FRAME "TYPE" FIELD HERE (ALWAYS 0)
  956.  
  957. IA_RC7:
  958.     LD    HL,(RX_BUF)    ;;; LOAD UP ADDRESS OF OUR CURRENT RX BUFFER
  959.     IN    A,(A_DAT)    ;;; GRAB THE PENDING CHARACTER
  960.     CALL    PUTCHAR        ;;; AND STUFF IN THIS PARTICULAR BUFFER
  961.     LD    (RX_BUF),HL    ;;; HL MIGHT HAVE CHANGED IN PUTCHAR()
  962.  
  963. ;;;*** NOTE!  THERE IS A PROBLEM HERE!  IF PUTCHAR() HAS NO MORE ROOM, THEN
  964. ;;; WE NEED TO FLUSH ALL FRAMES SO FAR ACCUMULATED & GO INTO RX_FLUSHING
  965. ;;; STATE !!! 3 FEB 87
  966.  
  967. IA_RC9:
  968.     POP    HL
  969.     POP    AF
  970.  
  971.     EI
  972.     RETI            ;;; NOTHING ELSE TO DO HERE
  973.  
  974.  
  975. ;;; IF NO ROOM, FLUSH THIS FRAME (SIGH)
  976. ;IA_RC5:
  977. ;    LD    A,TRUE
  978. ;    LD    (RX_FLUSHING),A    ;;; WE ARE IN THE MIDST OF FLUSHING THIS FRAME
  979. IA_RC2:
  980. ;    CALL    STA_ON        ;;;DDD NOTE THAT WE ARE IN FLUSHING STATE
  981. ;    IN    A,(A_DAT)
  982. ;    IN    A,(A_DAT)
  983. ;    IN    A,(A_DAT)
  984. ;    IN    A,(A_DAT)    ;;; EMPTY SIO SILO
  985. ;
  986. ;    JP    IA_RC9
  987.  
  988.  
  989. ;;;---------------------------------------------------------------------------
  990. ;;; FROM OUT POINT OF VIEW, THIS INTERRUPT IS ONLY INTERESTING BECAUSE IT
  991. ;;; TELLS US IF WE'RE AT END OF FRAME.
  992. IA_SPECIAL:
  993.     PUSH    AF
  994.     PUSH    HL        ;;; REGS WE'LL NEED
  995.  
  996.     LD    A,1
  997.     OUT    (A_CTL),A    ;;; READY TO READ RR1
  998.     IN    A,(A_CTL)    ;;; OK, GRAB RR1
  999.  
  1000. ;;; FIRST CHECK IF RX OVERRUN.  THIS IS VERY BAD, SO HALT.
  1001.     BIT    5,A
  1002.     JP    Z,IA_SP0    ;;; MOST OF THE TIME (ALL THE TIME?) GO THERE
  1003.  
  1004.     CALL    CON_ON
  1005.     CALL    STA_ON
  1006.  
  1007.     JP    RESTART        ; BPQ
  1008.  
  1009. IA_SP0:
  1010.     BIT    7,A        ;;; CHECK STATE OF END OF FRAME BIT
  1011.     JP    Z,IA_SP8    ;;; ELSE SOMETHING WEIRD HAPPENED - PROBABLY
  1012.                 ;;; RX OVERRUN. IN ANY CASE, FLUSH THIS FRAME.
  1013.                 ;;; ERROR RESET & THEN EXIT
  1014.                 ;;; THAT IS, TREAT LIKE IT WAS A CRC ERROR
  1015.  
  1016. ;;; IF END OF FRAME, CHECK CRC BIT FOR VALID.
  1017. IA_SP1:
  1018.     BIT    6,A        ;;; CHECK CRC ERROR BIT
  1019.     JP    NZ,IA_SP8    ;;; IF CRC ERROR BIT IS ON, THEN WAS CRC ERROR
  1020.  
  1021. ;;; FIRST ENSURE THAT WE INDEED HAVE A BUFFER ALLOCATED...
  1022.     LD    A,(RX_ALLOCATED_BUFFER)
  1023.     OR    A
  1024.     JP    Z,IA_SP9    ;;; IF NO BUFFER ALLOCATED, IGNORE THIS.
  1025.  
  1026. ;;; ELSE THIS WAS A GOOD FRAME, AND WE SHOULD SHIP IT OUT TO HOST
  1027. ;;; LEAVE THE FIRST CRC CHARACTER AT END OF BUFFER CHAIN IN THE BUFFER, AS
  1028. ;;; GETCHAR() WILL FLUSH IT.
  1029.  
  1030.     LD    HL,(RX_HEAD)
  1031.     CALL    OUT_QUEUE_INSERT    ;;; SHOVE THIS BUFFER STRING ONTO
  1032.                     ;;; OUTPUT QUEUE
  1033.     XOR    A
  1034.     LD    (RX_ALLOCATED_BUFFER),A    ;;; WE DON'T HAVE A BUFFER ALLOCATED
  1035.                     ;;; FOR THE NEXT FRAME...
  1036.     JP    IA_SP9
  1037.  
  1038. ;;; GET HERE IF THERE WAS A BAD CRC
  1039. IA_SP8:
  1040.     LD    A,(RX_ALLOCATED_BUFFER)    ;;; IF WE DON'T HAVE ANY BUFFERS
  1041.                     ;;; ALLOCATED, THEN 
  1042.     OR    A        ;;;8 FEB - SET CONDITION CODES !!!!!!
  1043.     JP    Z,IA_SP9    ;;; WE MUST NOT "RELEASE" THEM !!! 10 SEP 86
  1044.                 ;;; IF THEY ARE NOT ALLOCATED !!!
  1045. IA_SPF:
  1046.     XOR    A
  1047.     LD    (RX_ALLOCATED_BUFFER),A    ;;; NOT RECEIVING IF WE HAVE BAD CRC
  1048.     LD    HL,(RX_HEAD)
  1049.     CALL    FREE_CHAIN    ;;; FREE UP ALL BUFFER(S)
  1050.  
  1051. IA_SP9:
  1052.     LD    A,30H        ;;; ERROR RESET
  1053.     OUT    (A_CTL),A
  1054.     IN    A,(A_DAT)    ;;; AVOID SPURIOUS RCA INTERRUPT
  1055.  
  1056. ;    IN    A,(A_DAT)    ;;; AVOID SPURIOUS RCA INTERRUPT
  1057. ;    IN    A,(A_DAT)    ;;; AVOID SPURIOUS RCA INTERRUPT
  1058. ;    IN    A,(A_DAT)    ;;; AVOID SPURIOUS RCA INTERRUPT
  1059. ;                ;;; AND FLUSH SILO
  1060.     POP    HL
  1061.     POP    AF
  1062.  
  1063.     EI
  1064.     RETI
  1065.  
  1066. ;;;---------------------------------------------------------------------------
  1067. ;;; FOR EXT/STATUS INTERRUPTS ON MODEM, GET DCD STATE INTO MEMORY, AND
  1068. ;;; DEALLOCATE ANY SPURIOUS BUFFERS (BUFFER STUFF DONE 30 SEP 86).
  1069. IA_EXT:
  1070.     PUSH    AF
  1071.  
  1072.     LD    A,10H        ;;; RESET EXT/STATUS INTERRUPTS
  1073.     OUT    (A_CTL),A
  1074.     IN    A,(A_CTL)    ;;; GRAB RR0
  1075.     AND    DCD
  1076.     LD    (DCD_STATE),A    ;;;SAVE FOR TX KEYUP DCD DETECT.  IS 0 IF DCD
  1077.                 ;;;IS NOT ACTIVE, OR NON-ZERO IF IT IS ACTIVE.
  1078.  
  1079. ;
  1080.     LD    A,(RX_ALLOCATED_BUFFER)    ;;; IF WE ARE NOT IN THE
  1081. ;                    ;;; RECEIVING STATE...
  1082.     OR    A        ;;; THEN THERE ARE NO ALLOCATED BUFFERS AND...
  1083.     JP    Z,IA_EX9    ;;; WE MUST NOT "RELEASE" THEM !!! 10 SEP 86
  1084. ;                ;;; IF NO BUFFERS ALLOCATED !!!
  1085.     XOR    A
  1086.     LD    (RX_ALLOCATED_BUFFER),A    ;;; NOT RECEIVING
  1087.     PUSH    HL
  1088.     LD    HL,(RX_HEAD)
  1089.     CALL    FREE_CHAIN    ;;; FREE UP ALL BUFFER(S)
  1090.     POP    HL
  1091. ;
  1092. ;    WE HAVE JUST JUNKED THE FIRST PART OF THE FRAME, BUT THE RECEIVER
  1093. ;       MAY WELL STILL BE RUNNING (IF DCD HAS DROPPED WITHOUT LOSS OF
  1094. ;       DATA, WHICH CAN HAPPEN WITH STATE MACHINE DCD. IT SEEMS A GOOD
  1095. ;       TO RE-ENTER HUNT MODE
  1096. ;
  1097.     LD    A,33H        ; ERROR RESET, WR3
  1098.     OUT    (A_CTL),A
  1099.  
  1100.     LD    A,0D9H        ; ENTER HUNT    
  1101.     OUT    (A_CTL),A
  1102. ;
  1103. IA_EX9:
  1104.     POP    AF
  1105.  
  1106.     EI
  1107.     RETI
  1108.  
  1109. ;    INCLUDE    IB.MAC            ;TTY INTERRUPT CATCHERS
  1110.  
  1111. ;;;---------------------------------------------------------------------------
  1112. ;;; WE GET HERE WHENEVER -CTS, -DCD OR -SYNC INPUTS CHANGE, AS WELL AS BREAK
  1113. ;;; DETECTION. SINCE -DCD
  1114. ;;; IS ALWAYS TIED TO +5 VOLTS, WE NEED ONLY WORRY ABOUT -CTS AND -SYNC.
  1115. ;;; -CTS IS WIRED TO PIN 20, DTR, OF THE RS232 CONNECTOR, AND IS SUPPOSED TO
  1116. ;;; BE USED FOR HOST TO TNC HANDSHAKING; WE IGNORE THIS TRANSITION (WE ASSUME
  1117. ;;; THAT THE HOST IS ALWAYS READY).  WE ALSO IGNORE BREAK DETECTION.  WE ARE
  1118. ;;; ONLY INTERESTED IN -SYNC TRANSITIONS, SO WE CAN KEEP TIME.
  1119. ;;; NOTE!  THIS IS THE ONLY ROUTINE THAT IS ALLOWED TO USE THE OTHER REG SET!!
  1120. ;;; DEAL WITH BREAK DETECTION...
  1121.  
  1122. SYNC_HUNT    EQU    10H
  1123. IB_EXT:
  1124.     EX    AF,AF'
  1125.     EXX            ;;; WE WANT THE OTHER REGISTERS
  1126.     LD    A,10H
  1127.     OUT    (B_CTL),A    ;;; RESET EXT/STATUS INTERRUPTS
  1128.     IN    A,(B_CTL)    ;;; GRAB RR0
  1129.     LD    D,A        ;;; HOLD IT FOR A MOMENT...
  1130.     AND    SYNC_HUNT    ;;; ISOLATE THIS BIT
  1131.     JP    Z,IB_S0
  1132. ;ELSE SYNC/HUNT IS A 1
  1133.     LD    A,C
  1134.     OR    A
  1135.     JP    Z,IB_S1        ;;; GO HERE IF STATE OF SYNC/HUNT CHANGED
  1136.  
  1137.  
  1138. ;;; HERE IF SYNC/HUNT BIT DID NOT CHANGE - MAYBE SOMETHING ELSE DID....
  1139. IB_S9:
  1140.     LD    A,D        ;;; RETREIVE RRO FROM ABOVE
  1141.     AND    BREAK_ABORT    ;;; CHECK IF WE ARE DOING A BREAK/ABORT THING
  1142.     JP    Z,IB_NBA    ;;; THERE IF NO BREAK/ABORT
  1143.  
  1144. ;;; ELSE BREAK/ABORT BIT ON, NOTE STATE CHANGE...
  1145.     LD    A,1
  1146.     LD    (IN_BREAK),A    ;;; SAVE IN MEM  (PROBABLY CAN USE E REG...)
  1147.     IN    A,(B_DAT)    ;;; CLEAR OUT ANY NULL CHARACTER FROM BUFFER
  1148.     JP    IB_BOK        ;;; BREAK OK FOR NOW...
  1149.  
  1150. IB_NBA:        ;;;IF NO BREAK/ABORT, CHECK IF WE ARE IN BREAK/ABORT STATE.
  1151.     LD    A,(IN_BREAK)
  1152.     OR    A
  1153.     JP    Z,IB_BOK    ;;; NOTHING GOING ON, BREAK OK
  1154.  
  1155. ;;; ELSE WE WERE IN BREAK MODE, AND THIS IS THE TAIL END OF A BREAK.
  1156.     XOR    A
  1157.     LD    (IN_BREAK),A
  1158.     IN    A,(B_DAT)    ;;; DISCARD THE SINGLE EXTRANEOUS NULL
  1159. IB_BOK:
  1160. IB_S99:
  1161.     EX    AF,AF'
  1162.     EXX
  1163.     EI
  1164.     RETI            ;;; ELSE SOMETHING ELSE & WE DON'T CARE
  1165. IB_S0:                ;;; SYNC/HUNT IS A 0
  1166.     LD    A,C
  1167.     OR    A
  1168.     JP    NZ,IB_S1A    ;;; GO HERE IF SYNC/HUNT CHANGED
  1169.     JP    IB_S9        ;;; ELSE NOT INTERESTED, FORGET IT
  1170.  
  1171. ;GET HERE IF STATE OF SYNC/HUNT CHANGED
  1172. IB_S1:
  1173.     LD    C,1
  1174.     JP    IB_S1B
  1175. IB_S1A:                ;;; FIRST FIX UP C FOR NEXT TICK
  1176.     LD    C,0
  1177. IB_S1B:
  1178. ;;; HERE WHEN WE'VE SEEN A REAL "CLOCK TICK" & DEALT WITH C REG
  1179.     INC    B
  1180.     LD    A,B
  1181.     CP    12
  1182.     JP    NZ,IB_S99        ;;; WE ACT ON EVERY 12TH CLOCK TICK...
  1183.     LD    B,0            ;;; SO RELOAD DIVISOR. THIS GIVE US AN
  1184.                     ;;; EFFECTIVE INTERRUPT RATE OF 100 HZ
  1185.  
  1186. ;;; DECREMENT ALL THE TIMERS
  1187.  
  1188.     LD    HL,(TXQ_TIMERS)        ;;; GET FIRST TIMER VALUE, AND ...
  1189.     DEC    HL            ;;; ... DECREMENT IT AS REQUIRED.
  1190.     LD    (TXQ_TIMERS),HL
  1191.  
  1192.     LD    HL,(TXQ_TIMERS+2)    ;;; GET SECOND TIMER VALUE, AND ...
  1193.     DEC    HL            ;;; ... DECREMENT IT AS REQUIRED.
  1194.     LD    (TXQ_TIMERS+2),HL
  1195.  
  1196.     LD    HL,(TXQ_TIMERS+4)    ;;; GET THIRD TIMER VALUE, AND ...
  1197.     DEC    HL            ;;; ... DECREMENT IT AS REQUIRED.
  1198.     LD    (TXQ_TIMERS+4),HL
  1199.  
  1200.     LD    HL,(TXQ_TIMERS+6)    ;;; GET THIRD TIMER VALUE, AND ...
  1201.     DEC    HL            ;;; ... DECREMENT IT AS REQUIRED.
  1202.     LD    (TXQ_TIMERS+6),HL
  1203.  
  1204.     JP    IB_S99
  1205.  
  1206.  
  1207. ;;;---------------------------------------------------------------------------
  1208. IB_SPECIAL:
  1209.     PUSH    AF
  1210. IB_SP9:            ;;; NORMAL EXIT
  1211.     LD    A,30H        ;;; ERROR RESET
  1212.     OUT    (B_CTL),A
  1213.     POP    AF
  1214.     EI
  1215.     RETI
  1216.  
  1217. ;;;---------------------------------------------------------------------------
  1218. ;;; THE TX HAS BECOME EMPTY, SHOVE A NEW CHARACTER OUT
  1219. IB_TBE:
  1220.     PUSH    AF        ;;; NEW CHAR WILL RETURN IN A
  1221.     PUSH    HL
  1222.  
  1223.     LD    A,(IB_ESC_MODE)
  1224.     OR    A
  1225.     JP    Z,IB_T1        ;;; NOT ESCAPED, SO GO HERE
  1226. ;;; ELSE WE ARE ESCAPED, SO SEND ESCAPED CHAR
  1227.     LD    A,(IB_CHAR)    ;;; CHAR WHICH FOLLOWS ESCAPE
  1228.     OR    A
  1229.     JP    Z,IB_T2        ;;; SPECIAL CASE IF AT END OF FRAME, CLEAN UP
  1230.     OUT    (B_DAT),A
  1231.     XOR    A
  1232.     LD    (IB_ESC_MODE),A    ;;; GET OUT OF ESCAPED MODE
  1233.     JP    IB_T9        ;;; ALL FOR NOW...
  1234. IB_T1:
  1235.     LD    HL,(OUT_CHAIN_HEAD) ;;; WE ARE CURRENTLY ON THIS BUFFER, AS...
  1236.     CALL    GETCHAR        ;;; GETCHAR() NEEDS TO KNOW
  1237.     LD    (OUT_CHAIN_HEAD),HL ;;; MAYBE HL CHANGED, SO SAVE IT IN CASE
  1238.  
  1239.     JP    Z,IB_TDONE    ;;; IF NO MORE CHARS, DEAL WITH THIS
  1240.     CP    FESC
  1241.     JP    Z,IB_T1A    ;;; DEAL WITH FESC CHAR IN DATA STREAM
  1242.     CP    FEND
  1243.     JP    Z,IB_T1B    ;;; DEAL WITH FEND CHAR IN DATA STREAM
  1244. ;;; ELSE THIS CHAR IS NOTHING SPECIAL, SO SHOVE IT OUT
  1245.  
  1246.     OUT    (B_DAT),A    ;;; SHOVE IT OUT
  1247.     JP    IB_T9        ;;; IF THIS IS NOT LAST CHAR, ALL FOR NOW
  1248.  
  1249. ;;; ELSE THIS IS LAST CHAR, SEND FEND
  1250. IB_TDONE:
  1251.     LD    A,FEND
  1252.     OUT    (B_DAT),A
  1253.     LD    A,1
  1254.     LD    (IB_ESC_MODE),A    ;;; SET SPECIAL ESCAPED MODE BY...
  1255.     XOR    A
  1256.     LD    (IB_CHAR),A    ;;;... MAKING ESCAPED CHAR A 0
  1257.     JP    IB_T9        ;;; ALL TILL TX BUFFER GOES EMPTY AGAIN.
  1258.  
  1259. ; HERE IF ARE COMPLETELY DONE SENDING FRAME
  1260. IB_T2:
  1261.     PUSH    DE        ;;; NEED THIS FOR A MOMENT
  1262.     LD    HL,(OUT_HEAD_CBUF)
  1263.     INC    HL
  1264.     INC    HL        
  1265.     LD    DE,OUT_BOTTOM
  1266.     OR    A
  1267.     PUSH    HL
  1268.     SBC    HL,DE
  1269.     POP    HL        ;;; THIS MAY BE THE ONE WE WANT
  1270.     POP    DE
  1271.     JP    NZ,IB_T2A    ;;; YES IT IS!
  1272.  
  1273.     LD    HL,OUT_TOP    ;;; ELSE, MAKE A CIRCULAR BUFFER
  1274. IB_T2A:
  1275.     LD    (OUT_HEAD_CBUF),HL ;;; WE WILL WORK ON THIS ONE NEXT
  1276.     XOR    A
  1277.     LD    (OUT_STARTED),A    ;;; NOT DOING OUTPUTS ANYMORE
  1278.     LD    (IB_ESC_MODE),A    ;;; !!! NOT IN ESCAPED MODE ANYMORE !!!
  1279.  
  1280.     LD    A,28H        ;;; NEEDED FOR ASYNC
  1281.     OUT    (B_CTL),A    ;;; RESET TX INTERRUPT PENDING
  1282.  
  1283. IB_T9:
  1284.     POP    HL
  1285.     POP    AF
  1286.     EI
  1287.     RETI            ;;; NOW GET OUR BUTTS OUT OF HERE...
  1288.  
  1289. ;;; HERE IS FESC IN DATA STREAM
  1290. IB_T1A:
  1291.     OUT    (B_DAT),A    ;;; SHIP FESC CHARACTER TO PORT
  1292.     LD    A,TFESC        ;;; READY WHAT WILL BE NEXT CHAR
  1293. IB_T1Z:
  1294.     LD    (IB_CHAR),A    ;;; SET CHAR FOR NEXT TIME
  1295.     LD    A,1
  1296.     LD    (IB_ESC_MODE),A    ;;; WE ARE IN ESCAPED MODE
  1297.     JP    IB_T9        ;;; ALL FOR NOW
  1298.  
  1299. ;;; HERE IS FEND IN DATA STREAM
  1300. IB_T1B:
  1301.     LD    A,FESC
  1302.     OUT    (B_DAT),A
  1303.     LD    A,TFEND
  1304.     JP    IB_T1Z        ;;; REST IS SAME AS FESC CASE
  1305.  
  1306.  
  1307. ;;;---------------------------------------------------------------------------
  1308. ;;; GOT A CHAR FROM THE TTY PORT, DEAL WITH IT.
  1309.  
  1310. IB_RCA:
  1311.     PUSH    AF
  1312.  
  1313.     IN    A,(B_CTL)    ;;; READ RR0; FORCE REG POINTER TO BE 0
  1314.     LD    A,1
  1315.     OUT    (B_CTL),A    ;;; READY TO READ RR1
  1316.     IN    A,(B_CTL)    ;;; GRAB RR1
  1317.     AND    FRAMING_ERROR    ;;; ISOLATE THE FE BIT
  1318.     JP    Z,IB_RTOP    ;;; NO FRAMING ERROR, SO PROCESS THIS CHAR
  1319.  
  1320. ;;; ELSE WE HAVE A FRAMING ERROR - IGNORE THIS CHAR & FLUSH THIS FRAME...
  1321.     CALL    STA_OFF        ;;; OFF WITH THE LED!
  1322.     IN    A,(B_DAT)    ;;; FLUSH ERRONEOUS CHARACTER
  1323.     XOR    A
  1324.     LD    (IN_STATE),A    ;;; FORCE RECEIVER TO LOOK FOR FEND
  1325.     LD    A,(IN_ALLOCATED_BUFFER)
  1326.     OR    A
  1327.     JP    Z,IB_RC9    ;;; IF NO BUFFER IS ALLOCATED, DONE; EXIT.
  1328.  
  1329. ;;; ELSE WE WERE RECEIVING A DATA SLIP FRAME, SO FLUSH IT.
  1330.     PUSH    HL
  1331.     LD    HL,(IN_HEAD)
  1332.     CALL    FREE_CHAIN    ;;; DUMP THESE BUFFERS BACK TO FREE LIST
  1333.     POP    HL
  1334.     JP    IB_RC9        ;;; AND GET OUT OF HERE!
  1335.  
  1336. IB_RTOP:
  1337.     LD    A,(IN_STATE)    ;;; GET OUR STATE MACHINE VALUE
  1338.     OR    A
  1339.     JR    Z,IB_R0        ;;; IN STATE 0, WAITING FOR FEND
  1340.     CP    1
  1341.     JR    Z,IB_R1        ;;; IN STATE 1, SAW FEND
  1342.     CP    2
  1343.     JP    Z,IB_R2        ;;; IN STATE 2, DATA TO FOLLOW
  1344.     CP    3
  1345.     JP    Z,IB_R3        ;;; SAW FESC, EXPECTING TFESC OR TFEND
  1346.     CP    10
  1347.     JP    Z,IB_R10    ;;; EXPECTING TXDELAY
  1348.     CP    20
  1349.     JP    Z,IB_R20    ;;; EXPECTING P VALUE
  1350.     CP    30
  1351.     JP    Z,IB_R30    ;;; EXPECTING SLOTTIME VALUE
  1352.     CP    40
  1353.     JP    Z,IB_R40    ;;; EXPECTING TAILTIME VALUE
  1354.     CP    50
  1355.     JP    Z,IB_R50    ;;; EXPECTING FULL/HALF DUPLEX VALUE
  1356.  
  1357. ;ELSE WE DON'T KNOW WHAT HAPPENED, IGNORE IT.
  1358. IB_RCJUNK:
  1359.     IN    A,(B_DAT)
  1360.     XOR    A
  1361.     LD    (IN_STATE),A    ;;;GO INTO IN_STATE 0, FEND HUNT
  1362. IB_RC9:
  1363.     POP    AF        ;;; THROW IT AWAY, WE DON'T NEED JUNK
  1364.     EI
  1365.     RETI
  1366.  
  1367. ;;; HERE IF WE ARE HUNTING FOR FEND CHARACTER
  1368. IB_R0:
  1369.     CALL    STA_OFF
  1370.  
  1371.     IN    A,(B_DAT)
  1372.     CP    FEND
  1373.     JP    NZ,IB_RC9    ;;; IF WE DIDN'T SEE AN FEND, KEEP LOOKING
  1374.  
  1375. ;;; ELSE IS AN FEND, CHANGE STATE
  1376.     LD    A,1
  1377.     LD    (IN_STATE),A
  1378.     JP    IB_RC9
  1379.  
  1380. ;;; GET HERE IF WE'VE SEEN FEND CHARACTER; LOOK FOR COMMAND BYTE
  1381. IB_R1:
  1382.     CALL    STA_OFF
  1383.     IN    A,(B_DAT)
  1384.     CP    FEND
  1385.     JP    Z,IB_RC9    ;;; JUST ANOTHER FEND, KEEP LOOKING FOR CMD
  1386.  
  1387.     CALL    STA_ON        ;;;GETTING VALID SLIP; SHOW IN STA LED
  1388.  
  1389. ;;; HERE IF WE DO NOT HAVE AN FEND (EXPECTING COMMAND BYTE)
  1390.     OR    A
  1391.     JP    Z,IB_R1A    ;;; 0 COMMAND MEANS DATA WILL FOLLOW
  1392.     CP    1
  1393.     JP    Z,IB_R1B    ;;; 1 COMMAND MEANS TXDELAY WILL FOLLOW
  1394.     CP    2
  1395.     JP    Z,IB_R1C    ;;; 2 COMMAND MEANS P(PERSISTENCE) WILL FOLLOW
  1396.     CP    3
  1397.     JP    Z,IB_R1D    ;;; 3 COMMAND MEANS SLOT TIME WILL FOLLOW
  1398.     CP    4
  1399.     JP    Z,IB_R1E    ;;; 4 COMMAND MEANS TAILTIME TO FOLLOW
  1400.     CP    5
  1401.     JP    Z,IB_R1F    ;;; 5 COMMAND MEANS FULL/HALF DUPLEX TO COME
  1402.  
  1403. ;;; HERE IF WE RECEIVE BOGUS COMMAND BYTE, FLUSH REST OF FRAME
  1404.  
  1405.     CALL    STA_OFF        ;;;BOGOSITY, SO TURN OFF STA LED
  1406.  
  1407.     XOR    A
  1408.     LD    (IN_STATE),A    ;;; GO TO STATE WHICH LOOKS FOR FEND
  1409.     JP    IB_RC9
  1410.  
  1411. ;;; DATA ARE EXPECTED, CHANGE STATE
  1412. IB_R1A:
  1413.     LD    A,2
  1414.     LD    (IN_STATE),A
  1415.     JP    IB_RC9
  1416.  
  1417. ;;; TXDELAY TO FOLLOW, CHANGE STATE
  1418. IB_R1B:
  1419.     LD    A,10
  1420.     LD    (IN_STATE),A
  1421.     JP    IB_RC9
  1422.  
  1423. ;;; P TO FOLLOW, CHANGE STATE
  1424. IB_R1C:
  1425.     LD    A,20
  1426.     LD    (IN_STATE),A
  1427.     JP    IB_RC9
  1428.  
  1429. ;;; SLOTTIME TO FOLLOW, CHANGE STATE
  1430. IB_R1D:
  1431.     LD    A,30
  1432.     LD    (IN_STATE),A
  1433.     JP    IB_RC9
  1434.  
  1435. ;;; TAILTIME TO FOLLOW, CHANGE STATE
  1436. IB_R1E:
  1437.     LD    A,40
  1438.     LD    (IN_STATE),A
  1439.     JP    IB_RC9
  1440.  
  1441.  
  1442. ;;; FULL/HALF DUPLEX TO FOLLOW, CHANGE STATE
  1443. IB_R1F:
  1444.     LD    A,50
  1445.     LD    (IN_STATE),A
  1446.     JP    IB_RC9
  1447.  
  1448.  
  1449. ;;; THESE BYTES ARE DATA
  1450. IB_R2:
  1451.     IN    A,(B_DAT)
  1452.     CP    FEND
  1453.     JR    Z,IB_R2B    ;;; FEND MEANS TO QUEUE THIS BUFFER
  1454.     PUSH    AF        ;;; SAVE THE CHAR WE READ ON STACK FOR A BIT..
  1455.  
  1456.     LD    A,(IN_ALLOCATED_BUFFER)
  1457.     OR    A
  1458.     JP    NZ,IB_R2C    ;;; IF WE ALREADY ALLOCATED BUFFER
  1459.  
  1460.     PUSH    HL
  1461.     CALL    ALLOCATE_BUFFER    ;;; GET OUR INITIAL BUFFER TO MESS WITH
  1462.     JP    NZ,IB_R22
  1463.  
  1464. ;;;ELSE NO ROOM, FLUSH THIS FRAME
  1465.  
  1466.     POP    HL        ;;; KEEP STACK TIDY
  1467.     XOR    A
  1468.     LD    (IN_STATE),A
  1469.     JP    IB_RC9
  1470.  
  1471. IB_R22:
  1472.     LD    A,1
  1473.     LD    (IN_ALLOCATED_BUFFER),A    ;;; MAKE OURSELVES ACTIVE
  1474.  
  1475.     LD    (IN_BUFFER),HL
  1476.     LD    (IN_HEAD),HL    ;;; SAVE CURRENT & HEAD OF CHAIN POINTERS
  1477.     POP    HL
  1478.  
  1479. IB_R2C:
  1480.     POP    AF        ;;; RETREIVE THE DATA CHAR WE JUST GOT...
  1481.     CP    FESC
  1482.     JR    Z,IB_R2A    ;;; IF FESC IN DATA STREAM, SWITCH STATE
  1483.  
  1484.     PUSH    HL
  1485.     LD    HL,(IN_BUFFER)
  1486.     CALL    PUTCHAR        ;;; SHOVE THIS CHARACTER INTO OUR BUFFER
  1487.     LD    (IN_BUFFER),HL    ;;; SAVE IN CASE HL CHANGED
  1488.     POP    HL
  1489.     JP    IB_RC9        ;;; DONE SO FAR
  1490.  
  1491. ;;; FESC CHARACTER SEEN WHILE GRABBING DATA
  1492. IB_R2A:
  1493.     LD    A,3
  1494.     LD    (IN_STATE),A    ;;; GO TO THIS OTHER STATE
  1495.     JP    IB_RC9
  1496.  
  1497. ;;; FEND CHARACTER SEEN WHILE GRABBING DATA
  1498. IB_R2B:
  1499.     LD    A,(IN_ALLOCATED_BUFFER)
  1500.     OR    A
  1501.     JR    Z,IB_R2Z    ;;; NO BYTES ACCUMULATED, SO IS NULL FRAME
  1502.  
  1503. ;;; ELSE WE MUST SHIP THIS FRAME TO TX
  1504.     PUSH    HL        ;;; THIS BUG FOUND 29 SEP (MUST SAVE HL !!!)
  1505.     LD    HL,(IN_BUFFER)
  1506.     CALL    PUTCHAR        ;;; PUT A GARBAGE CHARACTER AT THE END OF
  1507.                 ;;; LAST BUFFER BECAUSE GETCHAR() WILL STRIP
  1508.                 ;;; IT. HACK NEEDED BECAUSE OF RX USE OF
  1509.                 ;;; PUTCHAR/GETCHAR.
  1510.      LD    HL,(IN_HEAD)
  1511.     CALL    TX_QUEUE_INSERT
  1512.     POP    HL
  1513.     XOR    A
  1514.     LD    (IN_ALLOCATED_BUFFER),A    ;;; INPUT NO LONGER ACTIVE
  1515. IB_R2Z:                ;;; ENTRY POINT FOR NULL FRAME
  1516.     LD    A,1        ;;; KEEP AS WAS, FENDS ONLY AT END IN V.32
  1517.     LD    (IN_STATE),A    ;;; GO LOOK FOR ANOTHER FRAME
  1518.  
  1519.     CALL    STA_OFF        ;;;DONE GETTING THIS FRAME, TURN STA LED OFF
  1520.  
  1521.     JP    IB_RC9
  1522.  
  1523.  
  1524. ;;; HERE IF WE'VE SEEN FESC IN DATA STREAM
  1525. IB_R3:
  1526.     IN    A,(B_DAT)
  1527.     CP    TFESC
  1528.     JR    Z,IB_R3A
  1529.     CP    TFEND
  1530.     JR    Z,IB_R3B
  1531.  
  1532. ;;; ELSE WE DON'T KNOW WHAT THE HELL IT IS, SO IGNORE & KEEP COLLECTING BYTES
  1533.     LD    A,2
  1534.     LD    (IN_STATE),A    ;;; GO BACK INTO "DATA RECEIVING" STATE
  1535.     JP    IB_RC9
  1536.  
  1537. ;;; HERE IF WE'VE SEEN TFESC AFTER AN FESC IN DATA STREAM; WRITE AN FESC
  1538. IB_R3A:
  1539.     LD    A,FESC
  1540. IB_R3Z:
  1541.     PUSH    HL
  1542.     LD    HL,(IN_BUFFER)
  1543.     CALL    PUTCHAR
  1544.     LD    (IN_BUFFER),HL
  1545.     POP    HL
  1546.     LD    A,2
  1547.     LD    (IN_STATE),A        ;;; GET OUT OF ESCAPED MODE
  1548.     JP    IB_RC9
  1549.  
  1550. ;;; HERE IF WE'VE SEEN TFEND AFTER FESC IN DATA STREAM; WRITE FEND
  1551. IB_R3B:
  1552.     LD    A,FEND
  1553.     JP    IB_R3Z            ;;; REST IS SAME AS FOR TFESC CASE
  1554.  
  1555.  
  1556. ;;; THIS CHARACTER IS INTERPRETED AS TXDELAY
  1557. IB_R10:
  1558.     IN    A,(B_DAT)
  1559.     LD    (TXDELAY),A
  1560.     XOR    A    
  1561.     LD    (IN_STATE),A    ;;; GO BACK TO FEND HUNT STATE
  1562.     JP    IB_RC9
  1563.  
  1564. ;;; THIS CHARCTER IS P, PERSISTENCE VALUE
  1565. IB_R20:
  1566.     IN    A,(B_DAT)
  1567.     LD    (PERSISTENCE),A
  1568.     XOR    A
  1569.     LD    (IN_STATE),A    ;;; GO BACK TO FEND HUNT STATE
  1570.     JP    IB_RC9
  1571.  
  1572. ;;; THIS CHARACTER IS SLOTTIME VALUE
  1573. IB_R30:
  1574.     IN    A,(B_DAT)
  1575.     LD    (SLOTTIME),A
  1576.     XOR    A
  1577.     LD    (IN_STATE),A    ;;; GO BACK TO FEND HUNT STATE
  1578.     JP    IB_RC9
  1579.  
  1580.  
  1581. ;;; THIS CHARACTER IS TAILTIME VALUE
  1582. IB_R40:
  1583.     IN    A,(B_DAT)
  1584.     LD    (TAILTIME),A
  1585.     XOR    A
  1586.     LD    (IN_STATE),A    ;;; GO BACK TO FEND HUNT STATE
  1587.     JP    IB_RC9
  1588.  
  1589.  
  1590. ;;; THIS CHARACTER IS FULL/HALF DUPLEX VALUE
  1591. ;;; 0 MEANS HALF DUPLEX, NON-ZERO MEANS FULL DUPLEX
  1592. IB_R50:
  1593.     IN    A,(B_DAT)
  1594.     LD    (FULL_DUPLEX),A
  1595.     XOR    A
  1596.     LD    (IN_STATE),A    ;;; GO BACK TO FEND HUNT STATE
  1597.     JP    IB_RC9
  1598.  
  1599. ;    INCLUDE    BUFFERS.MAC        ;ALL BUFFER-RELATED STUFF IN HERE
  1600.                     ;PLUS ALL (EVENTUALLY) VARIABLES
  1601. ;
  1602. ; THE BUFFER LIST IS KEPT FROM "BOTTOM" TO THE END OF RAM.  THE FORMAT OF THE
  1603. ; BUFFERS IS:
  1604.  
  1605. ;+------+--------+-------+---------------------------------------------------+
  1606. ;| NEXT | NBYTES | NREAD | DATA                             |
  1607. ;+------+--------+-------+---------------------------------------------------+
  1608. ;
  1609. ; 2 BYTES 1 BYTE   1 BYTE  124 BYTES  (TOTAL 128 BYTES)
  1610.  
  1611. ; NEXT     POINTER TO NEXT BUFFER ON THIS BUFFER CHAIN (OR 0 IF NO MORE)
  1612. ; NBYTES NUMBER OF BYTES IN THIS BUFFER THAT ARE VALID
  1613. ; NREAD  NUMBER OF BYTES READ FROM THIS BUFFER (USED BY GETCHAR)
  1614. ; DATA   124 BYTES OF DATA (NOT ALL IS NECESSARILY VALID, SEE NBYTES FIELD)
  1615. ;
  1616. ; THE BUFFER POOL IS ALL HERE, AND AS PROCESSES NEED BUFFER SPACE, IT IS ALL
  1617. ; ALLOCATED OUT OF THIS POOL.  SEE ALLOCATE_BUFFER AND FREE_BUFFER CODE.
  1618.  
  1619.  
  1620. ;;;---------------------------------------------------------------------------
  1621. ;;; RETURN IN HL A POINTER TO A FREE BUFFER.  IF THERE ARE NOT MORE BUFFERS,
  1622. ;;; RETURN WITH Z FLAG SET.
  1623. ;;; DESTROYS NO REGISTERS EXCEPT RETURN VALUE HL.
  1624. ;;; IS CALLED FROM AN INTERRUPT ROUTINE, SO THIS OPERATION IS ATOMIC.
  1625.  
  1626. ALLOCATE_BUFFER:
  1627.  
  1628.     PUSH    BC
  1629.     PUSH    AF
  1630.  
  1631.     LD    HL,(FREE)        ;;;GET POINTER TO HEAD OF FREE LIST
  1632.     LD    A,H
  1633.     OR    L
  1634.     JP    NZ,OK_ALLOCATE_BUFFER    ;;; ASSURE WE'RE NOT OFF THE END
  1635.  
  1636. ;GET HERE IF NO MORE BUFFERS.  RETURN Z SET - DO NOT DISTURB A.
  1637.  
  1638.     POP    AF
  1639.     LD    B,A            ;;; TUCK A AWAY FOR A MOMENT...
  1640.     XOR    A            ;;; TURN ON Z BIT
  1641.     LD    A,B            ;;; RETREIVE ORIGINAL A
  1642.     POP    BC
  1643.     RET
  1644.  
  1645. OK_ALLOCATE_BUFFER:
  1646.  
  1647.     XOR    A
  1648.     LD    C,(HL)            ;;;GRAB LO BYTE OF NEXT FREE BUFFER
  1649.     LD    (HL),A            ;;; CLEAR IT OUT
  1650.     INC    HL
  1651.     LD    B,(HL)            ;;; "LD BC,(HL)" NOW HI BYTE
  1652.     LD    (HL),A            ;;; CLEAR IT OUT, TOO
  1653.     LD    (FREE),BC        ;;; UPDATE WITH NEW FREE LIST POINTER
  1654.  
  1655.     DEC    HL            ;;; NOW HL IS AT HEAD OF NEW BUFFER
  1656.  
  1657.     POP    AF
  1658.     LD    B,A            ;;; TUCK A AWAY FOR A MOMENT...
  1659.     LD    A,1
  1660.     OR    A            ;;; TURN Z BIT OFF (I.E., ALL OK)
  1661.     LD    A,B            ;;; RETREIVE ORIGINAL A
  1662.  
  1663.     POP    BC
  1664.     RET
  1665.  
  1666. ;;;---------------------------------------------------------------------------
  1667. ;;; FREE_BUFFER GETS PASSED A POINTER (IN HL) TO A BUFFER TO BE FREED.  THE
  1668. ;;; BUFFER IS PLACED ON THE HEAD OF THE FREE LIST.  THE NBYTES & NREAD FIELDS
  1669. ;;; ARE MADE 0 BEFORE PLACING ON FREE LIST.
  1670. ;;; THIS ROUTINE IS CALLED AT INTERRUPT LEVEL, SO RESULTS ARE ATOMIC.
  1671. ;;; NO REGISTERS ARE DISTURBED AT ALL.  THE FREE POINTER IS UPDATED, HOWEVER.
  1672. ;;; 159 T STATES [ 63.6 USEC @ 2.5 MHZ ]
  1673.  
  1674. FREE_BUFFER:
  1675.     PUSH    AF
  1676.     PUSH    BC        ;;;WE'LL USE THESE
  1677.     PUSH    HL        ;;;THIS WILL BE NEW HEAD OF FREE LIST
  1678.  
  1679.     LD    BC,(FREE)    ;;;GET OLD FREE HEAD
  1680.     LD    (HL),C        ;;;PUT ON FREE CHAIN, FIRST LOW BYTE...
  1681.     INC    HL
  1682.     LD    (HL),B        ;;; ...NOW HI BYTE
  1683.     XOR    A
  1684.     INC    HL
  1685.     LD    (HL),A        ;;; ZERO OUT NBYTES FIELD
  1686.     INC    HL
  1687.     LD    (HL),A        ;;; AND THE NREAD FIELD OF NEW HEAD OF FREE
  1688.  
  1689.     POP    HL        ;;;GET NEW HEAD OF FREE LIST BACK
  1690.     LD    (FREE),HL    ;;;AND SAVE IT IN MEMORY WHERE IT BELONGS
  1691.  
  1692.     POP    BC
  1693.     POP    AF
  1694.     RET
  1695. ;;; --------------------------------------------------------------------------
  1696. ;;; PUTCHAR - HL CONTAINS POINTER TO BUFFER, A CONTAINS THE CHARACTER TO PUT
  1697. ;;; INTO THE BUFFER.  UPON RETURN, CHAR IS PUT INTO THIS BUFFER IF THER IS
  1698. ;;; ROOM, ELSE ANOTHER BUFFER IS ALLOCATED AND HL IS UPDATED TO POINT TO THIS
  1699. ;;; NEW BUFFER.  THE NEW BUFFER IS CHAINED ONTO THE OLD BUFFER IN THIS CASE.
  1700. ;;; THE CALLING ROUTINE IS RESPONSIBLE FOR MAINTAING BOTH THE HEAD OF A
  1701. ;;; PARTICULAR BUFFER CHAIN (IF IT NEEDS IT), AND THE CURRENT BUFFER BEING
  1702. ;;; MANIPULATED. THIS ROUTINE IS CALLED AT INTERRUPT LEVEL, SO IS ATOMIC.  NO
  1703. ;;; REGISTERS DISTURBED, EXCEPT THAT HL MAY HAVE A NEW VALUE.
  1704. ;;; 211 T STATES [  84.4 USEC @ 2.5 MHZ ]    NO NEW BUFFER REQUIRED
  1705. ;;; 338 T STATES [ 135.2 USEC @ 2.5 MHZ ]    NEW BUFFER NEEDED
  1706.  
  1707. PUTCHAR:
  1708.     PUSH    BC
  1709.     PUSH    IX
  1710.     PUSH    AF
  1711.     PUSH    HL        ;;;DO IT THIS WAY FOR A REASON...
  1712.  
  1713.     POP    IX        ;;;GET BUFFER POINTER INTO IX
  1714.     LD    A,(IX+2)    ;;;GRAB NBYTES FIELD
  1715.     CP    124        ;;;MAX OF 124 CHARS IN A BUFFER
  1716.     CALL    Z,PUTC_NEED_NEW_BUFFER
  1717. ;;; IF IT TAKES THIS CALL, IT RETURNS WITH A NEW BUFFER, WITH HL POINTING TO
  1718. ;;; IT (AS WELL AS IX), AND WITH A REG SET TO 0.
  1719. ;;; ELSE JUST PLUNK INTO BUFFER
  1720.     INC    (IX+2)        ;;;ONE MORE CHAR WILL GO INTO THIS BUFFER
  1721.     LD    C,A        ;;;GET PREVIOUS NBYTES
  1722.     XOR    A
  1723.     LD    B,A        ;;; BC <- NBYTES, FILLED OUT TO 16 BITS
  1724.     ADD    IX,BC        ;;; UPDATE IX TO POINT TO WHERE CHAR GOES
  1725.     POP    AF        ;;; RETREIVE THE CHAR WE WANT TO SAVE
  1726.     LD    (IX+4),A    ;;; SAVE IT IN THIS BUFFER
  1727.  
  1728.     POP    IX
  1729.     POP    BC
  1730.     RET            ;;;DONE FOR THE MOMENT
  1731.  
  1732. ;;; 127 T STATES [ 50.8 USEC @ 2.5 MHZ ] (REALLY PART OF PREV ROUTINE)
  1733. PUTC_NEED_NEW_BUFFER:        ;;;PREV BUFFER FILLED, GET A NEW ONE
  1734.     PUSH    DE        ;;; WORKING REGISTERS
  1735.     PUSH    HL        ;;; SAVE CURRENT BUFFER POINTER
  1736.     CALL    ALLOCATE_BUFFER    ;;; GRAB A NEW BUFFER, ADDR IS IN HL
  1737.  
  1738.     JP    Z,RESTART        ; NO BUFFERS - RESET WHOLE SYSTEM
  1739.  
  1740.     EX    DE,HL        ;;; "LD DE,HL" - GET NEW ADDR INTO DE FOR NOW
  1741.     POP    HL
  1742.     LD    (HL),E        ;;; LINK NEW BUFFER ONTO CHAIN, LO BYTE FIRST
  1743.     INC    HL
  1744.     LD    (HL),D        ;;; NOW HI BYTE, CHAINING DONE
  1745.  
  1746.     EX    DE,HL        ;;; UPDATE HL FOR ORIG. CALLING ROUTINE'S USE
  1747.     PUSH    HL
  1748.     POP    IX        ;;; UPPER ROUTINE NEEDS IX POINTING TO NEW BUF
  1749.     XOR    A        ;;; AND A IS NBYTES IN CALLING ROUTINE, MAKE..
  1750.                 ;;; ZERO FOR A NEW BUFFER
  1751.     POP    DE        ;;; DONE WITH THIS WORKING REGISTER
  1752.     RET            ;;; ALL DONE HERE, LET CALLING ROUTINE FINISH
  1753.  
  1754. ;;; --------------------------------------------------------------------------
  1755. ;;; GETCHAR - GRAB A CHARACTER FROM THE BUFFER POINTED AT BY HL, RETURN IN A.
  1756. ;;; IF THE "NREAD" FIELD OF THIS BUF = "NBYTES" THEN THIS BUFFER IS EXHAUSTED,
  1757. ;;; SO FOLLOW THE CHAIN ON TO THE NEXT BUFFER & RELEASE OLD BUFFER.  IF THE
  1758. ;;; NEXT CHAIN IS 0, OR IF THE NBYTES FIELD IS >= NREAD FIELD, THEN THERE ARE
  1759. ;;; NO MORE BYTES.  IN THIS CASE, RETURN WITH Z BIT SET; NORMALLY RETURN WITH
  1760. ;;; Z BIT RESET (THAT IS, NON-ZERO) INDICATING A VALID CHAR IS IN A.  NOTE
  1761. ;;; THAT IF WE NEED TO FOLLOW THE CHAIN TO A NEW BUFFER, HL WILL BE UPDATED,
  1762. ;;; TOO, SO THAT THE CALLING ROUTINE NEEDS TO DEAL WITH THIS.
  1763. ;;;         NO REGISTERS CHANGED EXCEPT AF AND POSSIBLY HL.
  1764. ;;; CALLED AT INTERRUPT LEVEL, SO OPERATION IS ATOMIC.
  1765. ;;; 212 T STATES [  84.8 USEC @ 2.5 MHZ ]    NO NEW BUFFER NEEDED
  1766. ;;; 493 T STATES [ 197.2 USEC @ 2.5 MHZ ]    IF FOLLOWING CHAIN
  1767.  
  1768. GETCHAR:
  1769.     PUSH    IX        ;;; SAVE BECAUSE IS WORKING REG
  1770.     PUSH    BC        ;;; WORKING REGS HERE
  1771.  
  1772.     PUSH    HL
  1773.     POP    IX        ;;; IX POINTS TO THIS BUFFER
  1774.  
  1775.     LD    A,(IX+3)    ;;; GRAB NREAD
  1776.     CP    (IX+2)        ;;; COMPARE WITH NBYTES
  1777.     CALL    Z,GETC_NEW_BUF    ;;; IF THEY ARE SAME, THIS BUFFER IS SPENT
  1778.  
  1779.     INC    (IX+3)        ;;; WE ARE READING ONE MORE CHAR, UPDATE NREAD
  1780.     INC    A
  1781.     CP    (IX+2)
  1782.     JP    NZ,GETC_PLUCK_CHARACTER    ;;; IF NOT LOOKING AT LAST CHARACTER
  1783.  
  1784. ;;; ELSE, IS THE "NEXT" POINTER 0?
  1785.     PUSH    HL
  1786.     LD    B,A        ;;; !!!!! SAVE  A   REG  !!!!!!! 4 JAN 87
  1787.     LD    A,(HL)
  1788.     INC    HL
  1789.     OR    (HL)
  1790.     LD    A,B        ;;; !!!! RESTORE A REG  (GASP!)
  1791.     POP    HL
  1792.     JR    NZ,GETC_PLUCK_CHARACTER
  1793.  
  1794. ;;; ELSE NEXT IS 0 AND WE ARE ON LAST CHAR - FLUSH IT & QUIT
  1795.     CALL    FREE_BUFFER
  1796.     POP    BC
  1797.     POP    IX
  1798.     RET            ;;; NOTE THAT Z BIT IS SET (FROM ABOVE)
  1799.  
  1800. ;;; ELSE WE CAN JUST PLUCK A CHARACTER OUT OF THIS BUFFER
  1801. GETC_PLUCK_CHARACTER:
  1802.     DEC    A        ;;; FIX A FROM ABOVE MUCKING AROUND...
  1803.  
  1804.     LD    C,A        ;;; GET OLD NREAD INTO BC
  1805.     LD    B,0        ;;; DITTO
  1806.     ADD    IX,BC        ;;; FIX BUFFER POINTER
  1807.     LD    A,1
  1808.     OR    A        ;;; MAKE Z BIT RESET
  1809.     LD    A,(IX+4)    ;;; GET THE DESIRED BYTE
  1810.  
  1811.     POP    BC
  1812.     POP    IX
  1813.     RET            ;;; ALL FOR THIS SIMPLE CASE
  1814.  
  1815. ;;; OLD BUFFER IS SPENT, GET NEW ONE (IF ANY)
  1816.  
  1817. GETC_NEW_BUF:
  1818.     PUSH    DE        ;;; NEED THIS REG HERE
  1819.     LD    E,(HL)        ;;; GET LO BYTE OF NEXT POINTER
  1820.     INC    HL
  1821.     LD    D,(HL)        ;;; HI BYTE OF NEXT POINTER (NOW ALL IN DE)
  1822.     DEC    HL        ;;; HL NOW BACK TO POINT AT SPENT BUFFER
  1823.     CALL    FREE_BUFFER    ;;; GIVE THE BUFFER BACK
  1824.  
  1825.     EX    DE,HL        ;;; "LD HL,DE" - FOLLOW CHAIN
  1826.     PUSH    HL
  1827.     POP    IX        ;;; INIT NEW IX (SAME AS HL IN THIS ROUTINE)
  1828.     XOR    A        ;;; A HOLDS NREAD (NEEDED ABOVE)
  1829.     POP    DE        ;;; RELEASE DE FROM USE BY THIS EXCURSION
  1830.     RET
  1831.  
  1832. ;;; --------------------------------------------------------------------------
  1833. ;;; FREE_CHAIN - MUST BE CALLED FROM INTERRUPT ROUTINE TO GUARANTEE
  1834. ;;; ATOMICITY.  TAKES BUFFER CHAIN POINTED AT BY HL AND RETURNS THEM TO FREE
  1835. ;;; BUFFER LIST
  1836. ;;; 303 T STATES + (N_ON_CHAIN-1)*238 T STATES
  1837. ;;; [ 121.2 USEC + (N_ON_CHAIN-1)*95.2 USEC ]
  1838.  
  1839. FREE_CHAIN:
  1840.     PUSH    AF
  1841.     PUSH    DE
  1842.     PUSH    HL        ;;; WE WILL MUCK WITH THESE
  1843.  
  1844. FC_0:
  1845.     LD    E,(HL)        ;;; GET LO PART OF NEXT BUFFER POINTER
  1846.     INC    HL
  1847.     LD    D,(HL)        ;;; NOW HI PART OF NEXT BUFFER POINTER
  1848.     DEC    HL
  1849.     CALL    FREE_BUFFER    ;;; RELEASE THIS BUFFER
  1850.     LD    A,D
  1851.     OR    E
  1852.     JP    Z,FC_9        ;;; IF "NEXT" ADDRESS IS 0, WE ARE AT END
  1853. ;;; ELSE WE'VE GOT MORE ON THIS CHAIN - DEAL WITH THEM.
  1854.     EX    DE,HL        ;;; "LD HL,DE" - HL POINTS TO "NEXT"
  1855.     JP    FC_0
  1856.  
  1857. FC_9:
  1858.     POP    HL
  1859.     POP    DE
  1860.     POP    AF
  1861.     RET
  1862.  
  1863. ;;; --------------------------------------------------------------------------
  1864. ;;; OUT_QUEUE_INSERT - PLACES THE JUST-RECEIVED BUFFER ON THE OUTPUT QUEUE.
  1865. ;;; THE ADDRESS OF THE RX BUFFER JUST RECEIVED IS IN HL.
  1866. ;;; THE OUTPUT QUEUE IS A CIRCULAR BUFFER.  THE OUTPUT ROUTINE KEEPS SENDING
  1867. ;;; OUT BUFFERS UNTIL ITS OUT_HEAD_CBUF POINTER EQUALS ITS OUT_TAIL_CBUF
  1868. ;;; POINTER. THE OUTPUT ROUTINE NEVER MUCKS WITH THE OUT_TAIL_CBUF POINTER;
  1869. ;;; SIMILARLY, THIS ROUTINE NEVER CHANGES THE OUT_HEAD_CBUF POINTER.  SO IT
  1870. ;;; IS POSSIBLE TO
  1871. ;;; INSERT NEW ENTRIES INTO THE OUTPUT CIRCULAR BUFFER QUEUE WITHOUT
  1872. ;;; DISTURBING THE ENTRY WHICH IS BEING SENT TO THE OUTPUT PORT.
  1873.  
  1874. OUT_QUEUE_INSERT:
  1875.     PUSH    AF
  1876.     PUSH    DE
  1877.     PUSH    HL        ;;; USE THESE
  1878.  
  1879.     EX    DE,HL        ;;; "LD DE,HL" - MOVE BUFFER TO LINK ADDR
  1880.     LD    HL,(OUT_TAIL_CBUF) ;;; GRAB NEXT FREE LOCATION 
  1881.     LD    (HL),E        ;;; SET LO ADDR 1ST
  1882.     INC    HL
  1883.     LD    (HL),D        ;;; NOW HI ADDR
  1884.     INC    HL        ;;; NOW HL POINTS TO NEXT FREE ENTRY IN...
  1885.     LD    DE,OUT_BOTTOM    ;;; ...CIRC BUF, UNLESS WE'RE AT END
  1886.     OR    A        ;;; CLEAR CARRY
  1887.     PUSH    HL        ;;; (MAY BE BE NEEDED ADDRESS)
  1888.     SBC    HL,DE
  1889.     POP    HL        ;;; GET BACK WHAT WE THINK IS GOOD
  1890.     JP    NZ,OQI_0
  1891.     
  1892.     LD    HL,OUT_TOP    ;;; GET HERE IF WE'RE AT END OF CIRC BUFFER.
  1893. OQI_0:
  1894.     LD    (OUT_TAIL_CBUF),HL
  1895.     POP    HL
  1896.     POP    DE
  1897.     POP    AF        ;;; KEEP CLEAN
  1898.     RET
  1899.  
  1900.  
  1901. ;;;---------------------------------------------------------------------------
  1902. ;;; TX_QUEUE_INSERT - SIMILAR TO OUT_QUEUE_INSERT, BUT WITH DIFFERENT QUEUE.
  1903. ;;; ALSO, INCREMENTS THE BYTE TX_OUTSTANDING (WHICH COUNTS THE NUMBER OF
  1904. ;;; FRAMES READY TO BE DUMPED TO THE MODEM PORT).  THIS ROUTINE, LIKE
  1905. ;;; OUT_QUEUE_INSERT, DOES NOT NEED TO WORRY ABOUT QUEUE WRAP-AROUND BECAUSE
  1906. ;;; THERE ARE MORE ENTRIES IN EACH OF THESE QUEUES THAN THERE ARE BUFFERS
  1907. ;;; AVAILABLE.  YES, I KNOW THIS IS A HACK, AND WASTES SOME RAM SPACE, BUT IT
  1908. ;;; MEANS I DON'T HAVE TO CHECK FOR OVERFLOWS HERE.
  1909. ;;; THE QUEUE IS CIRCULAR, AND SOMETIMES I CALL IT A "CBUF" - CIRCULAR BUFFER
  1910.  
  1911. TX_QUEUE_INSERT:
  1912.     PUSH    AF
  1913.     PUSH    DE
  1914.     PUSH    HL
  1915.     EX    DE,HL            ;;; "LD DE,HL" - SAVE CHAIN HEAD IN DE
  1916.     LD    HL,(TX_TAIL_CBUF)    ;;; NEXT FREE LOCATION IN TX CBUF
  1917.     LD    (HL),E
  1918.     INC    HL
  1919.     LD    (HL),D            ;;; PUT THIS CHAIN INTO TX QUEUE
  1920.     INC    HL            ;;; HL IS NEXT AVAILBLE TX QUEUE ...
  1921.     LD    DE,TX_BOTTOM        ;;; ... UNLESS WE ARE AT BOTTOM OF ...
  1922.     OR    A            ;;; ... THE TX QUEUE
  1923.     PUSH    HL
  1924.     SBC    HL,DE
  1925.     POP    HL
  1926.     JP    NZ,TQI_0        ;;; GO THERE IF NOT AT BUFFER BOTTOM
  1927.  
  1928.     LD    HL,TX_TOP        ;;; ELSE RELOAD WITH TOP OF QUEUE VAL
  1929. TQI_0:
  1930.     LD    (TX_TAIL_CBUF),HL    ;;; SAVE NEXT FREE QUEUE SLOT
  1931.     LD    HL,TX_OUTSTANDING
  1932.     INC    (HL)            ;;; +1 MORE FRAME OUTSTANDING NOW
  1933.     POP    HL
  1934.     POP    DE
  1935.     POP    AF
  1936.     RET
  1937.  
  1938. ;-----------------------------------------------------------------------------
  1939. ; SETUP HL & TX_CHAIN_HEAD FOR TRANSMISSION OF NEXT CHAIN.
  1940.  
  1941. TXNEXT_CBUF:
  1942.     PUSH    AF
  1943.     PUSH    DE
  1944.     LD    HL,(TX_HEAD_CBUF)
  1945.     LD    E,(HL)
  1946.     INC    HL
  1947.     LD    D,(HL)            ; DE -> NEXT CHAIN TO TRANSMIT
  1948.     INC    HL            ; HL MIGHT BE NEXT CBUF ENTRY POINTER
  1949.     PUSH    DE
  1950.     LD    DE,TX_BOTTOM
  1951.     OR    A            ;CLEAR CARRY
  1952.     PUSH    HL            ;SAVE WHAT MIGHT BE CORRECT VALUE
  1953.     SBC    HL,DE
  1954.     POP    HL
  1955.     POP    DE
  1956.     JP    NZ,TXN_1        ;GO THERE IF NOT AT END OF CIRC. BUF
  1957.  
  1958.     LD    HL,TX_TOP        ;ELSE WE WRAP AROUNE
  1959. TXN_1:
  1960.     LD    (TX_HEAD_CBUF),HL    ;SAVE NEXT CIRC BUF POINTER IN MEM
  1961.     EX    DE,HL            ;RETURN PTR TO NEXT CHAIN TO TX IN HL
  1962.     LD    (TX_CHAIN_HEAD),HL    ;TX RCA ROUTINE NEEDS THIS
  1963.     POP    DE
  1964.     POP    AF
  1965.     RET
  1966.  
  1967.  
  1968. ;-----------------------------------------------------------------------------
  1969. STA_ON:        ;TURN THE STA LED ON.  ASSUMES THAT INTERRUPTS ARE DISABLED!
  1970.     PUSH    AF
  1971.     LD    A,5
  1972.     OUT    (A_CTL),A        ;;; READY TO WRITE WR5
  1973.     LD    A,(A_WR5)        ;;; GET MEMORY COPY
  1974.     AND    0FFH-ALED        ;;; SET DTR BIT TO 0 SO LED GOES ON
  1975.     OUT    (A_CTL),A        ;;; ACTUALLY TURN ON STA LED NOW...
  1976.     LD    (A_WR5),A        ;;; UPDATE MEMORY COPY
  1977.     POP    AF
  1978.     RET
  1979. ;-----------------------------------------------------------------------------
  1980. STA_OFF:    ;TURN THE STA LED OFF.  ASSUMES THAT INTERRUPTS ARE DISABLED!
  1981.     PUSH    AF
  1982.     LD    A,5
  1983.     OUT    (A_CTL),A        ;;; READY TO WRITE WR5
  1984.     LD    A,(A_WR5)        ;;; GET MEMORY COPY
  1985.     OR    ALED            ;;; SET DTR BIT TO 1 SO LED GOES OFF
  1986.     OUT    (A_CTL),A        ;;; ACTUALLY TURN OFF STA LED NOW...
  1987.     LD    (A_WR5),A        ;;; UPDATE MEMORY COPY
  1988.     POP    AF
  1989.     RET
  1990.  
  1991. ;THESE ROUTINES MUST BE CALLED WITH INTERRUPTS DISABLED!
  1992. ;-----------------------------------------------------------------------------
  1993. STA_FLIP:
  1994.     PUSH    AF
  1995.     PUSH    BC
  1996.     IN    A,(A_CTL)        ;;;ASSURE WE ARE TALKING TO CH 0
  1997.     LD    A,5
  1998.     OUT    (A_CTL),A        ;;; READY TO WRITE WR5
  1999.     LD    A,(A_WR5)        ;;; GET MEMORY COPY
  2000.     LD    B,A            ;;; SAVE ORIGINAL FOR A MOMENT...
  2001.     AND    ALED            ;;; CHECK THE STA LED BIT
  2002.     LD    A,B            ;;; RETREIVE ORIGINAL
  2003.     JP    Z,STA_F0        ;;; BIT IS A 0, SO LED IS ON, MAKE OFF
  2004. ;ELSE MAKE IT GO ON (BECAUSE IT IS NOW OFF)
  2005.     AND    0FFH-ALED        ;;; SET DTR BIT TO 0 SO LED GOES ON
  2006.     JP    STA_F1
  2007. STA_F0:
  2008.     OR    ALED            ;;; SET DTR BIT TO 1 SO LED GOES OFF
  2009. STA_F1:
  2010.     OUT    (A_CTL),A        ;;; ACTUALLY TURN OFF STA LED NOW...
  2011.     LD    (A_WR5),A        ;;; UPDATE MEMORY COPY
  2012.     POP    BC
  2013.     POP    AF
  2014.     RET
  2015.     
  2016. ;-----------------------------------------------------------------------------
  2017. CON_ON:
  2018.     PUSH    AF
  2019.     LD    A,5
  2020.     OUT    (B_CTL),A
  2021.     LD    A,BLEDON
  2022.     LD    (B_WR5),A        ;;; SAVE IN MEM FOR FLIP ROUTINE
  2023.     OUT    (B_CTL),A
  2024.     POP    AF
  2025.     RET
  2026. ;-----------------------------------------------------------------------------
  2027. CON_OFF:
  2028.     PUSH    AF
  2029.     LD    A,5
  2030.     OUT    (B_CTL),A
  2031.     LD    A,BLEDOFF
  2032.     LD    (B_WR5),A        ;;; SAVE IN MEM FOR FLIP ROUTINE
  2033.     OUT    (B_CTL),A
  2034.     POP    AF
  2035.     RET
  2036. ;-----------------------------------------------------------------------------
  2037. CON_FLIP:
  2038.     PUSH    AF
  2039.     PUSH    BC
  2040.     IN    A,(B_CTL)        ;;;ASSURE WE ARE TALKING TO CH 0
  2041.     LD    A,5
  2042.     OUT    (B_CTL),A        ;;; READY TO WRITE WR5
  2043.     LD    A,(B_WR5)        ;;; GET MEMORY COPY
  2044.     LD    B,A            ;;; SAVE ORIGINAL FOR A MOMENT...
  2045.     AND    BLED            ;;; CHECK THE CON LED BIT
  2046.     LD    A,B            ;;; RETREIVE ORIGINAL
  2047.     JP    Z,CON_F0        ;;; BIT IS A 0, SO LED IS ON, MAKE OFF
  2048. ;ELSE MAKE IT GO ON (BECAUSE IT IS NOW OFF)
  2049.     AND    0FFH-BLED        ;;; SET DTR BIT TO 0 SO LED GOES ON
  2050.     JP    CON_F1
  2051. CON_F0:
  2052.     OR    BLED            ;;; SET DTR BIT TO 1 SO LED GOES OFF
  2053. CON_F1:
  2054.     OUT    (B_CTL),A        ;;; ACTUALLY TURN OFF CON LED NOW...
  2055.     LD    (B_WR5),A        ;;; UPDATE MEMORY COPY
  2056.     POP    BC
  2057.     POP    AF
  2058.     RET
  2059. ;
  2060. ;    IF CATASTROPHIC ERROR OCCURS RESET - IF RUNNING WITH BPQ
  2061. ;    SWITCH CODE, WE CANT REALLY AFFORT TO HANG UP
  2062. ;
  2063.  
  2064. RESTART:
  2065.     DI
  2066.     LD    HL,0
  2067. RSLOOP:
  2068.     DEC    HL
  2069.     LD    A,H
  2070.     OR    L
  2071.     JR    NZ,RSLOOP        ; DELAY A BIT
  2072.  
  2073.     JP    0            ; START AGAIN
  2074.  
  2075.     COND    PROM
  2076.  
  2077.     DEFS    START+8000H-$
  2078.  
  2079.     ENDC
  2080.  
  2081. FREE_RAM    DEFS    0
  2082.  
  2083.  
  2084. ;-----------------------------------------------------------------------------
  2085. ; THESE ARE THE TX REAL-TIME ROUTINE DATA STRUCTURES.  THEY ARE USED FOR
  2086. ; TIMING REQUIRED WITH TX CONTROL.  THERE ARE 3 ACTIONS THAT MUST BE TIMED:
  2087. ; 1) TXR_DELAY        TX DELAY TIMER (FOR TXDELAY FUNCTION)
  2088. ; 2) TXR_SLOTTIME    PART OF P-PERSISTENCE BACKOFF
  2089. ; 3) TXR_TAIL        TIMER TO BE SENDING SYNCS BEFORE DROPPING RTS
  2090.  
  2091. ; THE DATA STRUCTURE CAN BE THOUGHT OF LOGICALLY AS THIS:
  2092. ;
  2093. ;    +------------------------+
  2094. ;    | ROUTINE ENABLED (BYTE) | IS 0 IF NOT ENABLED, NON ZERO IF ENABLED
  2095. ;    +------------------------+--------------------------------------+
  2096. ;    | POINTER TO ROUTINE TO EXECUTE WHEN TIMER EXPIRES (WORD)    |
  2097. ;    +---------------------------------------------------------------+
  2098. ;    | 16-BIT DOWNCOUNTER TIMER VALUE, IN 10S OF MILLISECONDS (WORD)    |
  2099. ;    +---------------------------------------------------------------+
  2100. ;
  2101. ; THE DATA STRUCTURE HAS ONE ENTRY FOR EACH OF THE 3 TIMER EVENTS.  PHYSICALLY
  2102. ; IT IS ORGANIZED AS 3 SEPARATE LISTS, ONE FOR EACH OF THE ENABLES, ONE FOR
  2103. ; EACH OF THE ROUTINE POINTERS, AND ONE FOR EACH OF THE TIMER VALUES.
  2104. ;
  2105. ; AN INTERUPT ROUTINE, RUNNING AT 10 MILLISECOND TICKS, DECREMENTS THE VALUES
  2106. ; IN EACH OF THE DOWNCOUNT TIMER WHETHER A ROUTINE IS ENABLED OR NOT.  WHEN
  2107. ; DOWNCOUNT VALUE GOES TO 0 (OR NEGATIVE) THEN THE ROUTINE "FIRES".  THIS
  2108. ; CHECKING FOR "FIRING" HAPPENS AT NON-INTERRUPT LEVEL IN THE COMMUTATOR LOOP.
  2109. ; WITH THIS SCHEME, THE MINIMUM TIME BEFORE FIRING IS 10 MILLISECONDS, AND THE
  2110. ; MAXIMUM TIME IS 327.67 SECONDS (OVER 5 MINUTES).  FOR EXAMPLE, FOR A
  2111. ; TXDELAY OF 600 MILLISECONDS, THE TIMER WOULD GET LOADED WITH DECIMAL 60.
  2112. ;
  2113. ; WHEN A ROUTINE FIRES, IT GETS MARKED AS "DISABLED", SO YOU'D NEED TO
  2114. ; EXPLICITLY RE-ENABLE IT IF THIS IS REQUIRED
  2115.  
  2116. ; NOTE TOO THAT A CLOCK COULD BE EASILY IMPLEMENTED.  IF WE INSERTED ANOTHER
  2117. ; EVENT INTO OUR LIST WITH A TIMEOUT OF 100, THEN EVERY SECOND A ROUTINE WOULD
  2118. ; BE CALLED. IN THAT ROUTINE, WE COULD INCREMENT THE SECONDS FIELD (AND
  2119. ; POSSIBLY MINUTES, HOURS, DAYS, YEARS FIELDS) OF A TIME-OF-DAY CLOCK.  WE
  2120. ; WOULD IMMEDIATELY RE-ACTIVATE THIS TIMER TO GET THE NEXT TICK, ETC.
  2121.  
  2122.  
  2123. TXQ_ENABLES    DEFS    4        ; 4 BYTES FOR THE ENABLES
  2124.  
  2125. TXQ_ADDRESSES    DEFS    8        ; 4 WORDS FOR THE ROUTINE POINTERS
  2126.  
  2127. TXQ_TIMERS    DEFS    8        ; 4 WORDS FOR THE ROUTINE TIMERS
  2128.  
  2129. ; NOTE THE LAST SLOT IN THIS TABLE IS FOR R_TEST ROUTINE, WHICH BLINKS STA LED
  2130. ; IT IS NOT USED NORMALLY, JUST FOR HELPING ME DEBUG THIS!
  2131.  
  2132. ; SOME EQUATES TO SAVE US FROM DOING CONTORTED THINGS WHEN WE WANT TO CHECK IF
  2133. ; A ROUTINE IS ENABLED IN PLACES OTHER THAN THE COMMUTATOR LOOP, OR FOR
  2134. ; ENABLING ROUTINES, ETC.
  2135.  
  2136. TXQE_DELAY    EQU    TXQ_ENABLES+0
  2137. TXQE_SLOTTIME    EQU    TXQ_ENABLES+1
  2138. TXQE_TAIL    EQU    TXQ_ENABLES+2
  2139. TXQE_CWID    EQU    TXQ_ENABLES+3
  2140.  
  2141. ; SAME IDEA, BUT FOR THE TIMER VALUES
  2142.  
  2143. TXQT_DELAY    EQU    TXQ_TIMERS+0
  2144. TXQT_SLOTTIME    EQU    TXQ_TIMERS+2
  2145. TXQT_TAIL    EQU    TXQ_TIMERS+4
  2146. TXQT_CWID    EQU    TXQ_TIMERS+6
  2147.  
  2148. ; WE DON'T DO THIS FOR THE ROUTINE ADDRESSES, SINCE THEY DON'T CHANGE ONCE
  2149. ; THEY ARE INITIALIZED.
  2150.  
  2151.  
  2152. TXDELAY        DEFS    1        ; TRANSMITTER DELAY TIME VALUE
  2153.  
  2154. PERSISTENCE    DEFS    1        ; PERSISTENCE VALUE
  2155.  
  2156. SLOTTIME    DEFS    1        ; SLOT TIME VALUE
  2157.  
  2158. TAILTIME    DEFS    1        ; TX TAIL TIME VALUE
  2159.  
  2160.  
  2161. NBUFFERS    DEFS    1        ; UP TO 255 BUFFERS
  2162.  
  2163. FREE        DEFS    2        ; ADDRESS OF 1ST BUFFER ON FREE LIST
  2164.  
  2165.  
  2166. RX_BUF        DEFS    2        ; ADDRESS OF CURRENT RECEIVE BUFFER
  2167.  
  2168. RX_HEAD        DEFS    2        ; ADDRESS OF 1ST RX BUFFER
  2169.  
  2170. RX_ALLOCATED_BUFFER DEFS 1        ; SET NON-ZERO IF WE'RE IN RX STATE
  2171.  
  2172. RX_FLUSHING    DEFS    1        ; IS NON-0 IF WE RAN OUT OF BUFFER
  2173.                     ; SPACE AND ARE CURRENTLY FLUSHING THIS
  2174.                     ; FRAME BEING RECEIVED.  USED BY
  2175.                     ; IA_RCA AND RESET BY IA_EXT.
  2176.  
  2177.  
  2178. IN_BUFFER    DEFS    2        ; ADDR OF CURRENT INPUT BUFFER
  2179.  
  2180. IN_HEAD        DEFS    2        ; ADDR OF 1ST INPUT BUFFER
  2181.  
  2182. IN_ALLOCATED_BUFFER DEFS 1        ; IS NOT 0 IF WE'VE ALREADY ALLOC'D BUF
  2183.  
  2184. IN_STATE    DEFS    1 ; 1        ; INPUT STATE MACHINE STATE
  2185.                     ; ASSUME THAT WE'VE SEEN AN FEND FROM
  2186.                     ; (NON-EXISTENT) "PREVIOUS" FRAME. THIS
  2187.                     ; MEANS THAT WHEN WE ARE RECEIVING DATA
  2188.                     ; FROM USER, THERE NEED BE ONLY THE
  2189.                     ; FEND CHAR AT THE END OF A FRAME, AND
  2190.                     ; NOT AT THE BEGINNING (ALTHOUGH IF A
  2191.                     ; FEND IS AT THE BEGINNING, IT IS 
  2192.                     ; IGNORED.)
  2193.  
  2194. OUT_STARTED    DEFS    1        ; OUTPUT NOT STARTED YET (LOGICAL VAR)
  2195.  
  2196. OUT_HEAD_CBUF    DEFS    2 ; OUT_TOP    ; ADDRESS OF BUFFER TO BE OUTPUT RS232
  2197.  
  2198. OUT_TAIL_CBUF    DEFS    2 ; OUT_TOP    ; POINTER TO NEXT FREE OUTPUT BUFFER
  2199.  
  2200. OUT_CHAIN_HEAD    DEFS    2        ; ADDR OF BUFFER WE ARE NOW OUTPUTTING
  2201.  
  2202.  
  2203. TX_STARTED    DEFS    1        ; NON-ZERO IF WE'VE BEGUN TXING CHARS
  2204.  
  2205. TX_HEAD_CBUF    DEFS    2 ; TX_TOP    ; CURRENT ACTIVE CBUF ENTRY (IF ACTIVE)
  2206.  
  2207. TX_TAIL_CBUF    DEFS    2 ; TX_TOP    ; NEXT FREE CBUF ENTRY
  2208.  
  2209.  
  2210. TX_CHAIN_HEAD    DEFS    2        ; HOLDS ADDRESS OF THE CURRENT BUFFER
  2211.                     ; CHAIN HEAD THAT WE ARE TRANSMITTING
  2212.  
  2213. TX_OUTSTANDING    DEFS    1        ; NUMBER OF TX CBUFS QUEUED UP FOR TX
  2214.  
  2215.  
  2216. DCD_STATE    DEFS    1        ; IS NON 0 IF DCD LED IS ON
  2217.  
  2218.  
  2219. ;THESE NEXT TWO ARE USED BY THE IB_TBE INTERRUPT ROUTINE.
  2220.  
  2221. IB_ESC_MODE    DEFS    1        ; NOT IN ESCAPED MODE 
  2222.  
  2223. IB_CHAR        DEFS    1        ; NEXT CHAR TO SEND IF ESCAPED MODE
  2224.  
  2225. IN_BREAK    DEFS    1        ; NON-ZERO IF WE ARE IN A BREAK DETECT
  2226.                     ; ON THE ASYNC PORT
  2227.  
  2228. FULL_DUPLEX    DEFS    1        ; NOT INITIALLY FULL DUPLEX
  2229.  
  2230. A_WR5        DEFS    1 ; ALEDOFF    ; STATE OF STA LED & RTS (PTT) LINE,
  2231.                     ; MAINLY... (FOR CH A ONLY [MODEM] )
  2232.  
  2233. B_WR5        DEFS    1 ; BLEDOFF
  2234.         DEFS    1        ; WHY??
  2235.  
  2236. MINUTES        DEFS    1        ; FOR CWID TIMING
  2237. CWIDFLAG    DEFS    1        ; ID OUTSTANDING FLAG
  2238. CWIDPTR        DEFS    2        ; NEXT CWID BIT TO SEND
  2239. LASTBIT        DEFS    1        ; CURRENT CWID STATE
  2240.  
  2241. OUT_TOP        DEFS    2*255        ; "TOP" OF OUTPUT CIRCULAR BUFFER
  2242.                     ;  255 OUT BUFFER CHAINS PENDING, MAX
  2243. OUT_BOTTOM    DEFS    2        ; "BOTTOM" OF OUTPUT CIRCULAR BUFFER
  2244.  
  2245. TX_TOP        DEFS    255*2
  2246. TX_BOTTOM    DEFS    2
  2247.  
  2248.  
  2249. BOTTOM        DEFS    0        ; END OF ALL CODE & PREDEFINED DATA
  2250.  
  2251.  
  2252. ; NOTES ON NOMENCLATURE:
  2253.  
  2254. ;    OUT = TO TTY PORT; IN = FROM TTY PORT
  2255. ;    TX = TO MODEM; RX = FROM MODEM
  2256. ;
  2257. ;    ;;; MEANS THAT THAT CODE EXECUTES WITHOUT INTERRUPTS ENABLED (EXCEPT
  2258. ;        FOR THE INITIALIZATION CODE)
  2259. ;
  2260. ;
  2261. ; I HAVE BEEN CAREFUL WITH JR/JP USE.  I USE JP WHEN THE JUMP IS LIKELY AND
  2262. ; WHERE SPEED IS IMPORTANT.  I USE JR WHEN THE JUMP IS UNLIKELY SO THAT I CAN
  2263. ; SAVE A FEW CYCLES.  JP ALWAYS USES 10 CYCLES WHETHER IT JUMPS OR NOT, BUT
  2264. ; JR USES EITHER 7 OR 12 T STATES, NO JUMP/JUMP, RESPECTIVELY.
  2265.  
  2266.  
  2267. ; BUFFERS KEPT HERE AT END.
  2268.  
  2269.     END    START
  2270.  
  2271.  
  2272.